weblogic java.lang.NoSuchMethodError: javax.persistence.Table.indexes() 排錯記錄

記錄一下項目部署在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文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章