關於weblogic部署Java項目的包衝突問題

  咱們可能會用各類應用服務部署咱們的Java應用,好比Tomcat、WAS、weblogic等。Tomcat和WAS可能會比較少遇到一些奇怪的問題,可是用weblogic部署項目則常常遇到一些好比包衝突問題,路徑問題等奇怪但又常見的問題。
java

  今天我就講講關於weblogic部署Java項目包衝突的問題。下面我舉個例子:web

  當我在weblogic部署Java項目以後,啓動沒報任何錯,沒有異常。可是當我操做某個功能的時候頁面就報錯了:spring

         

  後臺報了這個錯:apache

Root cause of ServletException.
java.lang.LinkageError: loader constraint violation: loader (instance of weblogic/utils/classloaders/ChangeAwareClassLoader) 
previously initiated loading for a different type with name "javax/xml/namespace/QName" at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at weblogic.utils.classloaders.GenericClassLoader.defineClass(GenericClassLoader.java:343) at weblogic.utils.classloaders.GenericClassLoader.findLocalClass(GenericClassLoader.java:302) at weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClassLoader.java:270) at weblogic.utils.classloaders.ChangeAwareClassLoader.findClass(ChangeAwareClassLoader.java:64) at weblogic.utils.classloaders.ChangeAwareClassLoader.loadClass(ChangeAwareClassLoader.java:49) at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) at java.lang.Class.privateGetMethodRecursive(Class.java:3048) at java.lang.Class.getMethod0(Class.java:3018) at java.lang.Class.getMethod(Class.java:1784) at org.apache.xmlbeans.XmlBeans.buildMethod(XmlBeans.java:174) at org.apache.xmlbeans.XmlBeans.buildNoArgMethod(XmlBeans.java:190) at org.apache.xmlbeans.XmlBeans.buildGetContextTypeLoaderMethod(XmlBeans.java:200) at org.apache.xmlbeans.XmlBeans.<clinit>(XmlBeans.java:126) at org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook$Factory.newInstance(Unknown Source) at org.apache.poi.xssf.usermodel.XSSFWorkbook.onWorkbookCreate(XSSFWorkbook.java:290) at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:170) at com.kayak.web.base.util.export.ExportExcelXSSF.export(ExportExcelXSSF.java:893) at com.kayak.web.base.action.ExportExcelAction.exportExcel(ExportExcelAction.java:318) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868) at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227) at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125) at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:301) at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60) at com.kayak.web.user.filter.LoginCertifyFilter.doFilter(LoginCertifyFilter.java:125) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60) at com.kayak.web.base.filter.LocalRequestFilter.doFilter(LocalRequestFilter.java:28) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60) at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:27) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:60) at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3748) at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3714) at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120) at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2283) at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2182) at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1499) at weblogic.work.ExecuteThread.execute(ExecuteThread.java:263) at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)

  錯誤內容很長,可是要學會辨認,我剛開始就被一大堆錯誤誤導了。關鍵的都是下面的這個:mvc

loader (instance of weblogic/utils/classloaders/ChangeAwareClassLoader) 
previously initiated loading for a different type with name "javax/xml/namespace/QName"

  大概意思就是「加載器以前啓動的時候加載了名字叫javax/xml/namespace/QName的其餘類型的類」。其實轉換一下就是,在啓動的時候加載了一個javax/xml/namespace/QName類,咱們如今要用的功能須要一個類也叫javax/xml/namespace/QName,可是這個不是咱們真正想要的class。app

  從上面的意思能夠知道,這就是有兩個相同包包路徑和類名稱的class,可是有一個想要的卻沒有,只有一個咱們並不想要的class。瞭解weblogic部署的同窗都知道,weblogic加載了一個相同的class就不會在加載其餘同樣的class了。xss

  當我再操做一次的以後又報另外一個錯(部分錯誤內容):ui

 1 Root cause of ServletException.
 2 java.lang.NoClassDefFoundError: Could not initialize class org.apache.xmlbeans.XmlBeans
 3     at org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook$Factory.newInstance(Unknown Source)
 4     at org.apache.poi.xssf.usermodel.XSSFWorkbook.onWorkbookCreate(XSSFWorkbook.java:290)
 5     at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:170)
 6     at com.kayak.web.base.util.export.ExportExcelXSSF.export(ExportExcelXSSF.java:893)
 7     at com.kayak.web.base.action.ExportExcelAction.exportExcel(ExportExcelAction.java:318)
 8     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 9     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11     at java.lang.reflect.Method.invoke(Method.java:498)

  就是說不能初始化class  org.apache.xmlbeans.XmlBeans。可是咱們不要被這個所誤導,關鍵仍是在於上面的  javax/xml/namespace/QName ,就是由於這個衝突了因此纔會致使後面的問題發生。spa

  我用 jfind.jar  在項目下的lib目錄下搜索發如今axis-jaxrpc-1.4.jar下有 javax/xml/namespace/QName.class文件。由於在jdk下的 rt.jar 下面也有 javax/xml/namespace/QName.class因此就會有兩個同樣的class文件。code

               

  後面我發如今項目的 WEB-INF 下面有個 weblogic.xml 文件,裏面就有一些關於weblogic的配置:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <weblogic-web-app>
 3     <container-descriptor>
 4         <prefer-web-inf-classes>true</prefer-web-inf-classes>
 5     </container-descriptor>
 6     <charset-params>
 7         <input-charset>
 8             <resource-path>/*</resource-path>
 9             <java-charset-name>UTF-8</java-charset-name>
10         </input-charset>
11     </charset-params>
12 </weblogic-web-app>

  這個配置文件裏的第4行配置就是隻先加載項目裏的class文件,再加載weblogic的class,也就是由於這個配置而致使了項目裏的axis-jaxrpc-1.4.jar下有 javax/xml/namespace/QName.class,jdk下的 rt.jar 下面也有 javax/xml/namespace/QName.class卻沒有加載到,可是後者纔是程序所須要的。

  所以,我就嘗試把weblogic.xml的第4行配置 改爲 false,從新打war包,從新部署,而後發現問題解決了。

  接着我又換了一種嘗試,就是weblogic.xml的第4行配置依然是true ,可是我把項目裏那個衝突的class所在的包 axis-jaxrpc-1.4.jar 刪了,也從新打包部署,也沒有問題了。因此到此就把問題給解決了

  總結:

    1.  在weblogic中部署Java應用時,常常遇到包衝突問題,其實首先能夠經過修改weblogic.xml配置來解決,另外一種方式就是經過jfind.jar 找出衝突的class所在的包,直接把這個包刪了,能夠解決。

    2.  包衝突問題均可以經過上面的兩種方式解決,還有就是 有時候可能會包找不到某個class文件,其實頗有可能就是由於class文件衝突,以及前後加載的順序問題,致使咱們項目中真正須要的class文件卻沒有被加載進來。

相關文章
相關標籤/搜索