首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JBoss 5.1 + JDK 6 環境下 WebService 調用報「UnsupportedOperationException: setProperty must be overridden」解決實錄

     編輯:Java 相關知識

環境:JDK 1.6 + JBoss 5.1.0.GA。EJB 發布 WebService 成功,WSDL 可訪問,但 Axis 1 客戶端調用拋 SAXParseException: Premature end of file,服務端噴 UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage。本文記錄從客戶端誤導、關注服務端日志、定位 JDK 6 內置 SAAJ 與 JBoss 自帶 SAAJ 衝突、通過 endorsed 機制覆蓋系統類庫的完整解決路徑。

一、錯誤現象

客戶端

AxisFault
faultCode: {https://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultString: org.xml.sax.SAXParseException: Premature end of file.
...
at javax.xml.parsers.SAXParser.parse(Unknown Source)

現象:客戶端收到空響應/非 XML 內容,解析失敗。

服務端 (關鍵!)

ERROR [SOAPFaultHelperJAXWS] SOAP request exception
java.lang.UnsupportedOperationException: setProperty must be overridden by all subclasses of SOAPMessage
at javax.xml.soap.SOAPMessage.setProperty(Unknown Source)
at org.jboss.ws.core.soap.SOAPMessageImpl.<init>(SOAPMessageImpl.java:87)
at org.jboss.ws.core.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:215)
at org.jboss.wsf.stack.jbws.RequestHandlerImpl.processRequest(RequestHandlerImpl.java:455)
...

核心異常:SOAPMessage.setProperty 未被覆蓋。JBoss 的 SOAPMessageImpl 調用了父類 javax.xml.soap.SOAPMessage 的 setProperty,但 JDK 6 內置的 SAAJ (SOAP with Attachments API for Java) 實現是抽象類,未實現該方法,導致拋出 UnsupportedOperationException。

二、根因分析:JDK 6 內置 SAAJ vs JBoss 自帶 SAAJ 衝突

  • JDK 6 首次內置 SAAJ 1.3 API (javax.xml.soap.*) 與參考實現。
  • JBoss 5.1 自帶 jbossws-native-saaj.jar 等 WebService 棧庫,實現了 SAAJ 接口。
  • 類加載器遵循「雙親委派」,優先加載 JDK rt.jar 中的 SAAJ 類,導致 JBoss 自己的實現類 (SOAPMessageImpl) 繼承了 JDK 的抽象 SOAPMessage,調用父類未實現方法爆炸。

三、解決方案:Endorsed Standards Override Mechanism

利用 JDK endorsed 目錄優先於 rt.jar 加載類的特性,將 JBoss 的 SAAJ 實現 JAR 放入 JAVA_HOME/jre/lib/endorsed (或 JRE_HOME/lib/endorsed) 強制覆蓋 JDK 內置版本。

具體操作步驟

  1. 下載 jboss-5.1.0.GA-jdk6.zip (專為 JDK 6 編譯的 JBoss 版本),解壓。
  2. 從 JBOSS_HOME/lib/endorsed/ 複製以下 4 個 JAR:
    • jbossws-native-jaxrpc.jar
    • jbossws-native-jaxws.jar
    • jbossws-native-jaxws-ext.jar
    • jbossws-native-saaj.jar (核心)
  3. 在 JRE 目錄 創建 lib/endorsed 並粘貼 4 個 JAR:
    # Windows 示例
    C:\Program Files\Java\jre6\lib\endorsed\  (若無目錄自建)
    # Linux/Mac
    /usr/lib/jvm/java-6-sun/jre/lib/endorsed/
  4. 關鍵區別:
    • 從 Eclipse/MyEclipse 啟動 JBoss:使用的是 Eclipse 指向的 **JRE**,故 JAR 必須放在 **JRE_HOME/lib/endorsed**。
    • 從 命令行/腳本啟動 JBoss (run.sh/bat):使用的是 **JAVA_HOME** 指向的 JDK/JRE,故 JAR 也需放在 **JAVA_HOME/jre/lib/endorsed** (或 JDK 目錄下的 jre/lib/endorsed)。
    • 建議兩邊都放,一勞永逸。
  5. 重啟 JBoss,驗證 WebService 調用正常。

四、避坑指南與驗證

  • 不要只看客戶端異常:Premature end of file 是服務端拋異常導致響應為空/錯誤頁,根因在服務端日志。
  • 不要亂加 -Djava.endorsed.dirs:直接放入標準 endorsed 目錄最穩妥,避免啟動腳本參數傳遞錯誤。
  • 驗證生效:啟動日志中應見 SAAJ Meta Factory: org.jboss.ws.core.soap.SAAJMetaFactoryImpl 而非 JDK 內置工廠。
  • JBoss 6+/WildFly:已模塊化,不再存在此類衝突,升級是終極出路。

五、總結

JDK 6 內置 SAAJ API 與 JBoss 5.1 自帶實現衝突,導致 SOAPMessage.setProperty 未實現。通過 Endorsed 機制將 JBoss 4 個核心 WS JAR 注入 JRE/JDK,強制類加載器優先加載 JBoss 實現,徹底解決。核心教訓:**服務端異常才是真相,類加載器委派機制是定位此類 Jar 包衝突的利器**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved