環境: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。
javax.xml.soap.*) 與參考實現。jbossws-native-saaj.jar 等 WebService 棧庫,實現了 SAAJ 接口。rt.jar 中的 SAAJ 類,導致 JBoss 自己的實現類 (SOAPMessageImpl) 繼承了 JDK 的抽象 SOAPMessage,調用父類未實現方法爆炸。利用 JDK endorsed 目錄優先於 rt.jar 加載類的特性,將 JBoss 的 SAAJ 實現 JAR 放入 JAVA_HOME/jre/lib/endorsed (或 JRE_HOME/lib/endorsed) 強制覆蓋 JDK 內置版本。
JBOSS_HOME/lib/endorsed/ 複製以下 4 個 JAR:
jbossws-native-jaxrpc.jarjbossws-native-jaxws.jarjbossws-native-jaxws-ext.jarjbossws-native-saaj.jar (核心)lib/endorsed 並粘貼 4 個 JAR:
# Windows 示例
C:\Program Files\Java\jre6\lib\endorsed\ (若無目錄自建)
# Linux/Mac
/usr/lib/jvm/java-6-sun/jre/lib/endorsed/
jre/lib/endorsed)。Premature end of file 是服務端拋異常導致響應為空/錯誤頁,根因在服務端日志。endorsed 目錄最穩妥,避免啟動腳本參數傳遞錯誤。SAAJ Meta Factory: org.jboss.ws.core.soap.SAAJMetaFactoryImpl 而非 JDK 內置工廠。JDK 6 內置 SAAJ API 與 JBoss 5.1 自帶實現衝突,導致 SOAPMessage.setProperty 未實現。通過 Endorsed 機制將 JBoss 4 個核心 WS JAR 注入 JRE/JDK,強制類加載器優先加載 JBoss 實現,徹底解決。核心教訓:**服務端異常才是真相,類加載器委派機制是定位此類 Jar 包衝突的利器**。