先上一下自己的代码场景
就是自己在学习 使用cxf 发布 ws 的时候出现了问题
代码
@WebService接口类
@WebService public interface HelloService { String say(String name); }
@WebService实现类
@WebService public class HelloServiceImpl implements HelloService { public String say(String name) { return "hello。" + name + "本服务由cxf 提供"; } }
@使用jaxWs 来进行发布
public class JaxWsServer { private final static Logger log = Logger.getLogger(JaxWsServer.class.getName()); public static void main(String[] args) { JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean(); factory.setAddress("http://localhost:8080/ws/soap/hello"); factory.setServiceClass(HelloService.class); factory.setServiceBean(new HelloServiceImpl()); factory.create(); log.info("jax ws server provide soap ws is publish"); } }
由于我们的项目是使用maven 构建的 这里给出pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>me.czd.ws</groupId> <artifactId>soap-cxf</artifactId> <packaging>jar</packaging> <version>0.0.1-SNAPSHOT</version> <!-- 这里有一个神奇的地方 就是我们这里使用的 jetty是8.0版本的 但是spring boot 给我们的最新依赖是 9.0版本的 但是恰巧 两个版本中间存在着差异 最终导致 NoClassDefFoundError 错误 --> <parent> <groupId>me.czd</groupId> <artifactId>parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <name>soap-cxf</name> <url>http://maven.apache.org</url> <properties> <cxf.version>3.0.0</cxf.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>${cxf.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
这里写一下愿意,这个parent 项目是我自己写的,是为了使用springboot 的 pom 来进行一些jar包的管理
parent.pom
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>me.czd</groupId> <artifactId>parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <name>parent</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> <relativePath /> - <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> <!-- 构建这么工程的话,会同时扫描下面的子模块,并构建 --> <modules> <module>web</module> <module>dao</module> <module>service</module> </modules> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
当初想的是,通过parent 来进行jar包的版本的控制,这样子使用spring 的 感觉比较官方比较权威
这样运行会出现错误
六月 18, 2017 3:21:36 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://soap_cxf.ws.czd.me/}HelloServiceService from class me.czd.ws.soap_cxf.HelloService
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/jetty/server/SessionManager
at org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory.getOrCreate(JettyHTTPServerEngineFactory.java:116)
at org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory.createJettyHTTPServerEngine(JettyHTTPServerEngineFactory.java:268)
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.retrieveEngine(JettyHTTPDestination.java:120)
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.finalizeConfig(JettyHTTPDestination.java:153)
at org.apache.cxf.transport.http.HTTPTransportFactory.getDestination(HTTPTransportFactory.java:281)
at org.apache.cxf.binding.soap.SoapTransportFactory.getDestination(SoapTransportFactory.java:131)
at org.apache.cxf.endpoint.ServerImpl.initDestination(ServerImpl.java:84)
at org.apache.cxf.endpoint.ServerImpl.<init>(ServerImpl.java:63)
at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:160)
at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:211)
at me.czd.ws.soap_cxf.JaxWsServer.main(JaxWsServer.java:26)
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.server.SessionManager
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 11 more
这里就出现了很有意思的两个异常 ClassNotFoundException 和NoClassDefFoundError
这两个异常一定要明白怎么回事 一个类找不到,不存在异常,一个是 类编译了,但是运行的时候找不到,啊哈哈
然后自己百思不得其解,然后看了下依赖 自己项目的依赖是 8.0版本的,但是spring 给的是9.0版本的
这里两个分别的给出
parent中的 <jetty.version>9.4.5.v20170502</jetty.version>
cxf-rt-transports-http-jetty 中的依赖 <cxf.jetty.version>8.1.15.v20140411</cxf.jetty.version>
也就出现一个结果,jar包版本冲突了,然后经过了一下午的了解,最后把parent 这个 父工程给 注释了
然后代码就成功了,这里就是代码的目的就是一个发布 ws
但是通过这个ws 的demo 让我再次了解了 jar包冲突的原因,以及之后如何结果
这里只是简单的自己给定了一个版本
后期 多个jar 包,依赖的jar包版本不同,我们如何解决,就要使用maven提供的
单过滤依赖,这样子去接触依赖 <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase</artifactId> <version>0.94.17</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> 多过滤依赖,全部pass <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase</artifactId> <version>0.94.17</version> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> 哈哈世界清静
好了 自己解决了问题,自己也很开心,maven 我又攻克了一层