記錄一下項目部署在weblogic發生的java.lang.NoSuchMethodError: javax.persistence.Table.indexes()異常。
項目在tomcat中運行正常。部署到 weblogic12c時,運行報錯。
Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
排錯記錄
首先,在我們自己項目中搜索 javax.persistence.Table
類,發現其存在於 hibernate-jpa-2.1-api-1.0.0.Final.jar 包中。查看其類文件,發現其有定義 indexs()
方法。
我們可以確定,在weblogic環境中,項目運行時加載的 javax.persistence.Table
類並不是我們項目中提供的,可能來源於weblogic本身的類庫。雖然包名類名相同,可能版本不同,導致其定義不同,缺少了 indexs() 方法。
那麼,我們只要保證我們需要的類始終都從項目的類庫加載,就不會出問題。
當程序需要加載一個類時,weblogic默認的類加載機制是會優先在weblogic本身的類庫中查找,找到了就返回該class,找不到纔會在web項目的類庫中查找。
好在weblogic提供了一種方式,可以通過weblogic.xml配置文件顯式配置哪些類優先從項目中加載。
解決辦法
在項目 WEB-INF目錄下新建一個 weblogic.xml 文件,內容如下:(更多配置項,詳見文末參考鏈接)
配置說明了,在javax.persistence包下的類優先從 項目中加載。即可解決上述問題。
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app">
<container-descriptor>
<!-- 該包名下的類,優先從項目中加載 -->
<prefer-application-packages>
<package-name>javax.persistence</package-name>
<package-name>org.hibernate.jpa.internal</package-name>
</prefer-application-packages>
</container-descriptor>
</weblogic-web-app>
另附:
其實問題到這已經解決了,不過總感覺少了點什麼,我們好像還不知道從哪來的Table類導致了錯誤。
這裏只提供方法:
方法1:通過 java提供的-verbose:class
運行參數,能夠顯示類的加載路徑。
修改 opt/Oracle/Middleware/user_projects/domains/base_domain/bin/setDomainEnv.sh,
在文件頂部添加一行內容:JAVA_OPTIONS="$JAVA_OPTIONS -verbose:class"
。
重啓weblogic,即可在日誌查看具體的類加載信息。
方式2:通過weblogic自帶的類加載分析工具 Classloader Analysis Tool
具體使用參考此文檔:
https://blogs.perficient.com/2012/10/19/an-introduction-to-weblogic-server-classloader-analysis-tool/
https://docs.oracle.com/middleware/12213/wls/WLPRG/classloading.htm#WLPRG495
reference:
Weblogic 類加載分析工具
理解 WebLogic 類加載機制
weblogic.xml 配置文檔
WebLogic 類加載錯誤幫助文檔
WebLogic 各版本
WebLogic 8.1文檔