Just murmur

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” 就會過了

結果就是要用修改過的第四種方法才會過啦!浪費了我一整個下午!

參考