關(guān)于weblogic部署Java項(xiàng)目的包沖突問(wèn)題的解決
我們可能會(huì)用各種應(yīng)用服務(wù)部署我們的Java應(yīng)用,比如Tomcat、WAS、weblogic等。Tomcat和WAS可能會(huì)比較少遇到一些奇怪的問(wèn)題,但是用weblogic部署項(xiàng)目則經(jīng)常遇到一些比如包沖突問(wèn)題,路徑問(wèn)題等奇怪但又常見(jiàn)的問(wèn)題。
今天我就講講關(guān)于weblogic部署Java項(xiàng)目包沖突的問(wèn)題。下面我舉個(gè)例子:
當(dāng)我在weblogic部署Java項(xiàng)目之后,啟動(dòng)沒(méi)報(bào)任何錯(cuò),沒(méi)有異常。但是當(dāng)操作某個(gè)功能的時(shí)候頁(yè)面就報(bào)錯(cuò)了:
后臺(tái)報(bào)了這個(gè)錯(cuò):
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)
錯(cuò)誤內(nèi)容很長(zhǎng),但是要學(xué)會(huì)辨認(rèn),我剛開(kāi)始就被一大堆錯(cuò)誤誤導(dǎo)了。關(guān)鍵的都是下面的這個(gè):
loader (instance of weblogic/utils/classloaders/ChangeAwareClassLoader)
previously initiated loading for a different type with name "javax/xml/namespace/QName"
大概意思就是“加載器之前啟動(dòng)的時(shí)候加載了名字叫javax/xml/namespace/QName的其他類型的類”。其實(shí)轉(zhuǎn)換一下就是,在啟動(dòng)的時(shí)候加載了一個(gè)javax/xml/namespace/QName類,我們現(xiàn)在要用的功能需要一個(gè)類也叫javax/xml/namespace/QName,但是這個(gè)不是我們真正想要的class。
從上面的意思可以知道,這就是有兩個(gè)相同包包路徑和類名稱的class,但是有一個(gè)想要的卻沒(méi)有,只有一個(gè)我們并不想要的class。了解weblogic部署的同學(xué)都知道,weblogic加載了一個(gè)相同的class就不會(huì)在加載其他一樣的class了。
當(dāng)我再操作一次的之后又報(bào)另一個(gè)錯(cuò)(部分錯(cuò)誤內(nèi)容):
Root cause of ServletException. java.lang.NoClassDefFoundError: Could not initialize class org.apache.xmlbeans.XmlBeans 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)
就是說(shuō)不能初始化classorg.apache.xmlbeans.XmlBeans。但是我們不要被這個(gè)所誤導(dǎo),關(guān)鍵還是在于上面的javax/xml/namespace/QName ,就是因?yàn)檫@個(gè)沖突了所以才會(huì)導(dǎo)致后面的問(wèn)題發(fā)生。
我用 jfind.jar 在項(xiàng)目下的lib目錄下搜索發(fā)現(xiàn)在axis-jaxrpc-1.4.jar下有javax/xml/namespace/QName.class文件。因?yàn)樵趈dk下的 rt.jar 下面也有javax/xml/namespace/QName.class所以就會(huì)有兩個(gè)一樣的class文件。
后面我發(fā)現(xiàn)在項(xiàng)目的 WEB-INF 下面有個(gè)weblogic.xml 文件,里面就有一些關(guān)于weblogic的配置:
<?xml version="1.0" encoding="UTF-8"?> <weblogic-web-app> <container-descriptor> <prefer-web-inf-classes>true</prefer-web-inf-classes> </container-descriptor> <charset-params> <input-charset> <resource-path>/*</resource-path> <java-charset-name>UTF-8</java-charset-name> </input-charset> </charset-params> </weblogic-web-app>
這個(gè)配置文件里的第4行配置就是只先加載項(xiàng)目里的class文件,再加載weblogic的class,也就是因?yàn)檫@個(gè)配置而導(dǎo)致了項(xiàng)目里的axis-jaxrpc-1.4.jar下有javax/xml/namespace/QName.class,jdk下的rt.jar 下面也有javax/xml/namespace/QName.class卻沒(méi)有加載到,但是后者才是程序所需要的。
因此,我就嘗試把weblogic.xml的第4行配置 改成 false,重新打war包,重新部署,然后發(fā)現(xiàn)問(wèn)題解決了。
接著我又換了一種嘗試,就是weblogic.xml的第4行配置依然是true ,但是我把項(xiàng)目里那個(gè)沖突的class所在的包 axis-jaxrpc-1.4.jar 刪了,也重新打包部署,也沒(méi)有問(wèn)題了。所以到此就把問(wèn)題給解決了
總結(jié):
1. 在weblogic中部署Java應(yīng)用時(shí),經(jīng)常遇到包沖突問(wèn)題,其實(shí)首先可以通過(guò)修改weblogic.xml配置來(lái)解決,另一種方式就是通過(guò)jfind.jar 找出沖突的class所在的包,直接把這個(gè)包刪了,可以解決。
2. 包沖突問(wèn)題都可以通過(guò)上面的兩種方式解決,還有就是 有時(shí)候可能會(huì)包找不到某個(gè)class文件,其實(shí)很有可能就是因?yàn)閏lass文件沖突,以及先后加載的順序問(wèn)題,導(dǎo)致我們項(xiàng)目中真正需要的class文件卻沒(méi)有被加載進(jìn)來(lái)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于Spring Boot動(dòng)態(tài)權(quán)限變更問(wèn)題的實(shí)現(xiàn)方案
這篇文章主要介紹了Spring Boot動(dòng)態(tài)權(quán)限變更實(shí)現(xiàn)的整體方案使用session作為緩存,結(jié)合AOP技術(shù)進(jìn)行token認(rèn)證和權(quán)限控制,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-06-06Java鏈表數(shù)據(jù)結(jié)構(gòu)及其簡(jiǎn)單使用方法解析
這篇文章主要介紹了Java鏈表數(shù)據(jù)結(jié)構(gòu)及其簡(jiǎn)單使用方法解析,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07Java擴(kuò)展庫(kù)RxJava的基本結(jié)構(gòu)與適用場(chǎng)景小結(jié)
RxJava(GitHub: https://github.com/ReactiveX/RxJava)能夠幫助Java進(jìn)行異步與事務(wù)驅(qū)動(dòng)的程序編寫,這里我們來(lái)作一個(gè)Java擴(kuò)展庫(kù)RxJava的基本結(jié)構(gòu)與適用場(chǎng)景小結(jié),剛接觸RxJava的同學(xué)不妨看一下^^2016-06-06Mybatis 一級(jí)緩存與二級(jí)緩存的實(shí)現(xiàn)
mybatis作為一個(gè)流行的持久化工具,緩存必然是缺少不了的組件。通過(guò)這篇文章,就讓我們來(lái)了解一下一級(jí)緩存與二級(jí)緩存的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05將Java的List結(jié)構(gòu)通過(guò)GSON庫(kù)轉(zhuǎn)換為JSON的方法示例
GONS是Google在GitHub上開(kāi)源的Java類庫(kù),提供各種Java對(duì)象和JSON格式對(duì)象之間的轉(zhuǎn)換功能,將Java的List結(jié)構(gòu)通過(guò)GSON庫(kù)轉(zhuǎn)換為JSON的方法示例2016-06-06教你如何測(cè)試Spring Data JPA的Repository
Spring Data JPA 提供了一些便捷的方式來(lái)測(cè)試這種持久層的代碼,常見(jiàn)的兩種測(cè)試類型是集成測(cè)試和單元測(cè)試,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-08-08