WSDL2Java 出現 Two declarations cause a collision in the ObjectFactory class 的錯誤
問題
測試 PlateSpin Recon Web Service API,要用 Apache CXF 內的 WSDLToJava 時出現的問題
直接執行 WSDLToJava PerformanceDataCollectionWS.wsdl 出現 WSDLToJava Error: Thrown by JAXB: Two declarations cause a collision in the ObjectFactory class. at line 263 column 90 of schema file:/home/cwweng/workspace/recon/PerformanceDataCollectionWS.wsdl 的錯誤。結果是因為 PerformanceDataCollectionWS.wsdl 下面的這一段出問題
<s:complexType name="MonitorFilter">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="_sumInstances" type="s:boolean" />
<!-- 省略 -->
<s:element minOccurs="1" maxOccurs="1" name="SumInstances" type="s:boolean" />
<!-- 省略 -->
</s:sequence>
</s:complexType>
因為 _sumInstances 和 SumInstances 會產生相同的 property
解法
網路上解法有很多個,但幾乎都沒用
第 1 種
加上 -autoNameResolution
的參數,測試結果是……無效,一樣的錯誤訊息。
第 2 種
透過 JAXB binding 讓 _ 不要被移掉:
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:s="http://www.w3.org/2001/XMLSchema"
version="1.0">
<jaxb:globalBindings underscoreBinding="asCharInWord"/>
</jaxb:bindings>
參數加上 -b binding.xml
錯誤訊息變成了 WSDLToJava Error: java.lang.IllegalArgumentException: trying to create the same field twice: sumInstances
第 3 種
用 JAXWS binding 把 _sumInstances 改成 underscoreBinding
<jaxws:bindings version="1.0"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
wsdlLocation="PerformanceDataCollectionWS.wsdl"
xmlns="http://java.sun.com/xml/ns/jaxws"
xmlns:tns1="VOLARISWS">
<jaxws:schemabindings>
<jaxws:bindings node="wsdl:definitions">
<jaxws:bindings node="//s:element[@nam='_sumInstances']">
<jaxb:property name="underscoreSumInstances" />
</jaxws:bindings>
</jaxws:bindings>
</jaxws:schemabindings>
</jaxws:bindings>
參數一樣是 -b binding.xml,結果錯誤訊息變成了 WSDLToJava Error: Could not find any node with the XPath expression: //wsdl:definitions///s:element[@nam=’_sumInstances’]
WTF !!!
第 4 種
用 JAXB binding 把 _sumInstances 改成 underscoreBinding
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:s="http://www.w3.org/2001/XMLSchema"
version="1.0">
<jaxb:bindings schemaLocation="file:PerformanceDataCollectionWS.wsdl" node="/s:schema">
<jaxb:bindings node="//s:element[@name='_sumInstances']">
<jaxb:property name="underscoreSumInstances"></jaxb:property>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
結果錯誤訊息變成了 WSDLToJava Error: Thrown by JAXB: “file:/PerformanceDataCollectionWS.wsdl” is not a part of this compilation. Is this a mistake for “file:/PerformanceDataCollectionWS.wsdl#types1”? at line 6 column 91 of schema file:/binding.xml。快瘋了
正確解答
這一篇說 Won’t Fix ! 應該要用 JAXWS 而不是 JAXB (前面用 JAXWS 就吃屎啦)。 裡面有提到解法就是把 binding.xml 裡的 schemaLocation 檔名結尾加上 #types1 變成 schemaLocation=”file:PerformanceDataCollectionWS.wsdl#types1” 就會過了
結果就是要用修改過的第四種方法才會過啦!浪費了我一整個下午!