2012-05-28 59 views
3

TL; DR出於某種原因,我無法在使用CXF的Java優先Web服務中解組一個相當簡單的對象。CXF錯誤解組錯誤UnsupportedOperationException

我有一個Java的第一CXF Web服務使用類似的API:

@WebMethod 
public SearchResponse search(@WebParam(name = "searchRequest") SearchRequest searchRequest);  

響應(類不會和解組)大致是:

public class SearchResponse { 

    private List<SearchResult> results; 
    public List<SearchResult> getResults() { 
     return results; 
    } 
    public void setResults(List<SearchResult> results) { 
     this.results = results; 
    } 
} 

信息搜索結果是死簡單的兩個財產類別:

public class SearchResult { 
    private long id; 
    private String name; 

    public long getId() { 
     return id; 
    } 
    public void setId(long id) { 
     this.id = id; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
} 

我可以通過Soap-UI調用此服務,它工作完美年。然而,當我打電話使用JAXWS客戶我得到一個錯誤:

javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: null 
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:143) 
    at $Proxy67.search(Unknown Source) 
    at com.blah.MyTest.curseYouSearch(MyTest.java:76) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59) 
    at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98) 
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79) 
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87) 
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77) 
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42) 
    at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88) 
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51) 
    at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44) 
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27) 
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37) 
    at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
Caused by: java.lang.UnsupportedOperationException 
    at java.util.AbstractList.add(AbstractList.java:131) 
    at java.util.AbstractList.add(AbstractList.java:91) 
    at com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:290) 
    at com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:254) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Scope.add(Scope.java:106) 
    at com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty$ReceiverImpl.receive(ArrayERProperty.java:195) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.endElement(UnmarshallingContext.java:524) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleEndElement(StAXStreamConnector.java:206) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:170) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:351) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:330) 
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:610) 
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:530) 
    at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:114) 
    at org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:99) 
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236) 
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:658) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:2139) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:2022) 
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1947) 
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:66) 
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:632) 
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62) 
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236) 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:472) 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:302) 
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:254) 
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73) 
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:123) 
    ... 24 more 

我可以設置AbstractList.add斷點和基於它出現解組正試圖添加到空單,從而導致堆棧上的當然是不可變的:

Thread [main] (Suspended (breakpoint at line 131 in AbstractList)) 
    Collections$EmptyList(AbstractList<E>).add(int, E) line: 131  
    Collections$EmptyList(AbstractList<E>).add(E) line: 91 
    Lister$CollectionLister<BeanT,T>.addToPack(T, Object) line: 290 
    Lister$CollectionLister<BeanT,T>.addToPack(Object, Object) line: 254  
    Scope<BeanT,PropT,ItemT,PackT>.add(Accessor<BeanT,PropT>, Lister<BeanT,PropT,ItemT,PackT>, ItemT) line: 106 
    ArrayERProperty$ReceiverImpl.receive(UnmarshallingContext$State, Object) line: 195 
    UnmarshallingContext.endElement(TagName) line: 524 
    StAXStreamConnector.handleEndElement() line: 206  
    StAXStreamConnector.bridge() line: 170 
    UnmarshallerImpl.unmarshal0(XMLStreamReader, JaxBeanInfo) line: 351 
    UnmarshallerImpl.unmarshal(XMLStreamReader, Class<T>) line: 330 
    JAXBEncoderDecoder.unmarshall(Unmarshaller, Object, QName, Class<?>, boolean) line: 610 
    JAXBEncoderDecoder.unmarshall(Unmarshaller, Object, MessagePartInfo, boolean) line: 530 
    DataReaderImpl<T>.read(MessagePartInfo, T) line: 114  
    DocLiteralInInterceptor.handleMessage(Message) line: 99 
    PhaseInterceptorChain.doIntercept(Message) line: 236  
    ClientImpl.onMessage(Message) line: 658 
    HTTPConduit$WrappedOutputStream.handleResponseInternal() line: 2139 
    HTTPConduit$WrappedOutputStream.handleResponse() line: 2022 
    HTTPConduit$WrappedOutputStream.close() line: 1947 
    HTTPConduit(AbstractConduit).close(Message) line: 66  
    HTTPConduit.close(Message) line: 632  
    MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(Message) line: 62 
    PhaseInterceptorChain.doIntercept(Message) line: 236  
    ClientImpl.invoke(BindingOperationInfo, Object[], Map<String,Object>, Exchange) line: 472 
    ClientImpl.invoke(BindingOperationInfo, Object[], Exchange) line: 302 
    ClientImpl.invoke(BindingOperationInfo, Object...) line: 254  
    JaxWsClientProxy(ClientProxy).invokeSync(Method, BindingOperationInfo, Object[]) line: 73 
    JaxWsClientProxy.invoke(Object, Method, Object[]) line: 123 
    ...endless stack lines omitted... 

我的客戶是在春季設置爲JAXWS:客戶端:

<jaxws:client id="searchServiceClient" 
    serviceClass="qualified.class.of.Service" 
    address="${url.searchService}"> 
</jaxws:client> 

我們有許多其他的網絡服務,在一個非常相似的方式返回列表和WO很好;我對這個有什麼不同是有點遺憾的。

該系統使用Java 6,CXF 2.2.3。

任何建議將是最受歡迎的。

+0

你解決了這個問題嗎? –

回答

3

我覺得我遭受了同樣的問題,至少在我的情況下有一個解決方案,它可能會幫助你。

此處的用例與您的用例略有不同,因爲我正在從平面應用程序中讀取XML文件。沒有網絡交互。

配置文件的顯著要素是:

private static final List<StrategyConfiguration<Transaction>> EMPTY_CONFIGURATION_LIST = Collections.emptyList(); 
private List<StrategyConfiguration<Transaction>> configurations; 
@XmlElementWrapper(name = "boundaries") 
@XmlElements({ 
    @XmlElement(name = "a", type = abtStrategyConfig.class), 
    @XmlElement(name = "b", type = bbtStrategyConfig.class), 
    @XmlElement(name = "c", type = cbtStrategyConfig.class) 
}) 
public void setConfigurations(List<StrategyConfiguration<Transaction>> configurations) { 
    this.configurations = configurations; 
} 
public List<StrategyConfiguration<Transaction>> getConfigurations() { 
    if (configurations == null) { 
     return EMPTY_CONFIGURATION_LIST; 
    } 
    return configurations; 
} 

我還沒來得及探討「爲什麼」,而是一個調試運行表明,「是什麼」這是導致該問題。無效的「get」訪問器在setter之前被調用。我想這是提供一個類型安全檢查。 「空白」列表正在被返回,非空,然後被用作後續集合的基礎。

我發現通過提供一個直接setter & getter,然後提供一個用於外部使用的零安全getter我清除了錯誤。

private static final List<StrategyConfiguration<Transaction>> EMPTY_CONFIGURATION_LIST = Collections.emptyList(); 
private List<StrategyConfiguration<Transaction>> configurations; 
@XmlElementWrapper(name = "boundaries") 
@XmlElements({ 
    @XmlElement(name = "a", type = abtStrategyConfig.class), 
    @XmlElement(name = "b", type = bbtStrategyConfig.class), 
    @XmlElement(name = "c", type = cbtStrategyConfig.class) 
}) 
public void setJaxBConfigurations(List<StrategyConfiguration<Transaction>> configurations) { 
    this.configurations = configurations; 
} 
public List<StrategyConfiguration<Transaction>> getJaxBConfigurations() { 
    return configurations; 
} 
public List<StrategyConfiguration<Transaction>> getConfigurations() { 
    List<StrategyConfiguration<Transaction>> response = getConfigurationConfigs(); 
    if (response == null) { 
     response = EMPTY_CONFIGURATION_LIST; 
    } 
    return response; 
}