jar冲突问题解决方法记录

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

jar冲突问题解决方法记录
目录
1 问题现象 (2)
2 处理方法 (2)
2.1 测试环境 (2)
2.2 访问报错情况 (2)
2.3 错误查找步骤 (3)
2.3.1 参数配置 (3)
2.3.2 启动程序查看verbose:class监视效果 (3)
3 处理冲突 (4)
4 总结 (4)
1问题现象
前期做了一个简单的rest服务端应用。

开发测试期都在windows下的
java+tomcat下运行,一直运行良好。

最近为了进行技术培训,准备把该示例放到Linux的服务上。

直接动手,同样版本的java+tomcat在我的Linux服务器(Ubuntu14.04的虚拟机)上走起。

轻松运行起来,没问题。

好吧,自己简单测试一下。

index.jsp没问题,service页面,也没问题。

点击查看wadl。

哦,404。

2处理方法
既然windows下没问题,Linux下有问题,明细是有jar冲突,在windows 中和Linux中ClassLoader加载到了不同的jar中的同名class。

那咱就把他找出来。

最简单粗暴的方法:日志中已经指明了出错的类,那么只要知道报错时使用的class加载自那个jar,和正确时的class加载自那个jar,那不就能轻松搞定了。

思路有了,开始找工具方法。

2.1测试环境
Windows环境(不报错):
Windows7 (64位) + jdk1.8.0_60(64位) + tomcat-8.0.26(64位)
Linux环境(访问wadl报错):
Ubuntu14.04.1(X86_64)+ jdk1.8.0_60(64位) + tomcat-8.0.26(64位) 2.2访问报错情况
ng.NoClassDefFoundError: javax/ws/rs/MessageProcessingException org.apache.cxf.jaxrs.impl.ResponseBuilderImpl.build(ResponseBuilderImp l.java:69)
org.apache.cxf.jaxrs.model.wadl.WadlGenerator.handleRequest(WadlGenera tor.java:257)
org.apache.cxf.jaxrs.impl.RequestPreprocessor.handleMetadataRequest(Re questPreprocessor.java:216)
org.apache.cxf.jaxrs.impl.RequestPreprocessor.checkMetadataRequest(Req uestPreprocessor.java:200)
org.apache.cxf.jaxrs.impl.RequestPreprocessor.preprocess(RequestPrepro cessor.java:84)
org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAX RSInInterceptor.java:117)
org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXR SInInterceptor.java:101)
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseIntercepto rChain.java:271)
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitia tionObserver.java:121)
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractH TTPDestination.java:239)
org.apache.cxf.transport.servlet.ServletController.invokeDestination(S ervletController.java:223)
org.apache.cxf.transport.servlet.ServletController.invoke(ServletContr oller.java:203)
org.apache.cxf.transport.servlet.ServletController.invoke(ServletContr oller.java:137)
org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpri ngServlet.java:159)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(Abs tractHTTPServlet.java:286)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTT PServlet.java:211)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractH TTPServlet.java:262)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 2.3错误查找步骤
2.3.1参数配置
根据以上错误信息判断,应当是系统中javax.ws.rs包存在冲突。

在Linux下进行tomcat启动命令配置。

修改catalina.sh。

在其中增加
JAVA_OPTS的设置:JAVA_OPTS="$JAVA_OPTS -verbose:class"
作为对比在windows下进行tomcat启动命令配置。

修改catalina.out,在其中增加JAVA_OPTS的设置:set "JAVA_OPTS=%JAVA_OPTS% -verbose:class"
2.3.2启动程序查看verbose:class监视效果
分别启动tomcat。

在Linux下,错误日志记录到catalina.out中。

在windows 下默认会输出到console中。

为便于查看输出日志,在windows下可以使用catalina.bat run > ..\logs\tomcat.log 2>&1将console的日志重定向到日志文件
tomcat.log中。

在Linux的日志catalina.out中,查找相应的包javax.ws.rs。

根据日志信息:[Loaded javax.ws.rs.GET from
file:/apache-tomcat-8.0.26/webapps/demoapp/WEB-INF/lib/jsr311-api-1.0.jar] 可知,该包从javax.ws.rs-api-2.0.1.jar中加载(出错时往往会发现,同一个包,会从不同的jar中加载class)。

检查发现在该jar中没有
javax.ws.rs.MessageProcessingException类。

而在tomcat的日志中,查找相应的包javax.ws.rs。

根据日志信息:
[Loaded javax.ws.rs.MessageProcessingException from
file:/D:/appserver/tomcat/tomcat-8.0.26/webapps/demoapp/WEB-INF/lib/javax.ws.r s-api-2.0-m10.jar]可知javax.ws.rs在以上两个jar中均存在。

3处理冲突
使用解压缩工具查看两个jar包。

根据Linux下出错的错误提示,查看javax.ws.rs.MessageProcessingException类并比较两个jar判断其等效性。

在此次处理中,看到javax.ws.rs-api-2.0-m10.jar可以包含jsr311-api-1.0.jar。

简单删掉jsr311-api-1.0.jar即可处理冲突。

删掉jsr311-api-1.0.jar,再在Linux启动程序,进行测试,直接搞定。

最后,当然记着把-verbose:class去掉。

4总结
通过此次问题处理经历,可以判断jar冲突问题均可以采用此方法解决。

Linux下和windows下java加载顺序存在一些细微差别。

建议程序部署前都在现场OS及软件环境下进行测试。

什么:没有现场服务器的操作系统应用服务环境?试试用docker构建一个现场服务器环境。

现场使用AIX,solaris……。

别担心,他们都投入容器怀抱,宣布支持Docker了。

相关文档
最新文档