为什么wsdl2java生成的代码随意使用CXF依赖?
Why wsdl2java generated code use CXF dependencies at will?
我使用 Apache CXF 3.0.4 wsdl2java
通过以下命令从 this wsdl 生成代码:
./wsdl2java -client -exsh true -d weather -p weather -verbose url
据我所知,wsdl2java
仅使用 JAX-WS 生成纯 java 代码。生成的代码在没有任何额外 library/dependency 的情况下工作正常。我已经用 grep 找到任何 CXF classes,但它似乎没有 CXF。当我将特定的 CXF 依赖项添加到我的 pom.xml
时,问题就出来了。这个依赖是:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.0</version>
</dependency>
添加这个之后,应用程序似乎使用了不同的 JAX-WS 实现(甚至可能吗?)。
生成的代码除其他外还包含 WeatherSoap
接口。其中一种方法是 getWeatherInformation()
@WebService(targetNamespace = "http://ws.cdyne.com/WeatherWS/", name = "WeatherSoap")
@XmlSeeAlso({ObjectFactory.class})
public interface WeatherSoap {
/**
* Gets Information for each WeatherID
*/
@WebResult(name = "GetWeatherInformationResult", targetNamespace = "http://ws.cdyne.com/WeatherWS/")
@RequestWrapper(localName = "GetWeatherInformation", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "weather.GetWeatherInformation")
@WebMethod(operationName = "GetWeatherInformation", action = "http://ws.cdyne.com/WeatherWS/GetWeatherInformation")
@ResponseWrapper(localName = "GetWeatherInformationResponse", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "weather.GetWeatherInformationResponse")
public weather.ArrayOfWeatherDescription getWeatherInformation();
...
}
无cxf-rt-frontend-jaxws
依赖
- 进入
getWeatherInformation()
调试导致 GetWeatherInformation
( 另一个生成 class.
- 进入
GetWeatherInformation
导致com.oracle.webservices.internal.api.message.BasePropertySet
- ...
- 收到来自 SOAP 网络服务的结果。
具有cxf-rt-frontend-jaxws
依赖性
- 进入
getWeatherInformation
而调试导致 org.apache.cxf.jaxws.JaxWsClientProxy
(为什么?)
- ...
- 抛出异常:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Could not find conduit initiator for address: http://wsf.cdyne.com/WeatherWS/Weather.asmx and transport: http://schemas.xmlsoap.org/soap/http
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
at com.sun.proxy.$Proxy33.getWeatherInformation(Unknown Source)
at weather.WeatherSoap_WeatherSoap_Client.main(WeatherSoap_WeatherSoap_Client.java:49)
Caused by: java.lang.RuntimeException: Could not find conduit initiator for address: http://wsf.cdyne.com/WeatherWS/Weather.asmx and transport: http://schemas.xmlsoap.org/soap/http
at org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:224)
at org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:229)
at org.apache.cxf.endpoint.AbstractConduitSelector.createConduit(AbstractConduitSelector.java:145)
at org.apache.cxf.endpoint.AbstractConduitSelector.getSelectedConduit(AbstractConduitSelector.java:107)
at org.apache.cxf.endpoint.UpfrontConduitSelector.prepare(UpfrontConduitSelector.java:63)
at org.apache.cxf.endpoint.ClientImpl.prepareConduitSelector(ClientImpl.java:853)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:511)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
... 2 more
我知道有针对此异常的解决方法 here 并且它有效。但不适用于我的工作申请。毕竟它会抛出 NPE:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: java.lang.NullPointerException
...
Caused by: org.apache.cxf.binding.soap.SoapFault: java.lang.NullPointerException
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:86)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:52)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:41)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:802)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1642)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1533)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1336)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:652)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
... 7 more
提问时间
- 为什么即使没有 Apache-CXF 应用程序也能正常工作,为什么还要使用它?
- 在这种情况下是否可以强制应用程序停止使用 Apache-CXF?
我不需要客户端的这种依赖关系(因为没有它们它也能正常工作)。我也只想制作 SOAP。这就是为什么我需要这种依赖关系。我看到的唯一解决方案是将应用程序拆分为单独的消费者和生产者。
application seems to use different implementation of JAX-WS( is it even possible?).
是的。 CXF 有它自己的 jax-ws 提供程序,它的 jar 包含一个声明它的服务文件。 (当 JVM 需要一个 jax-ws 提供者时:它会查看类路径以查看是否声明了一个非默认提供者...并且如果有的话 使用它)。
为什么?
那是 Java 规格:http://docs.oracle.com/javaee/5/api/javax/xml/ws/spi/Provider.html#provider()
Is it possible to force application to stop using Apache-CXF in this case?
是的。在您的类路径上创建适当的资源文件以重定向到默认实现。
详细信息:文件必须在此处:META-INF/services/javax.xml.ws.spi.Provider
(如果您使用 maven:简单地放在此处:/src/main/resources/META-INF/services/javax.xml.ws.spi.Provider
)
并且必须包含一行:
javax.xml.ws.spi.Provider
我使用 Apache CXF 3.0.4 wsdl2java
通过以下命令从 this wsdl 生成代码:
./wsdl2java -client -exsh true -d weather -p weather -verbose url
据我所知,wsdl2java
仅使用 JAX-WS 生成纯 java 代码。生成的代码在没有任何额外 library/dependency 的情况下工作正常。我已经用 grep 找到任何 CXF classes,但它似乎没有 CXF。当我将特定的 CXF 依赖项添加到我的 pom.xml
时,问题就出来了。这个依赖是:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.0</version>
</dependency>
添加这个之后,应用程序似乎使用了不同的 JAX-WS 实现(甚至可能吗?)。
生成的代码除其他外还包含 WeatherSoap
接口。其中一种方法是 getWeatherInformation()
@WebService(targetNamespace = "http://ws.cdyne.com/WeatherWS/", name = "WeatherSoap")
@XmlSeeAlso({ObjectFactory.class})
public interface WeatherSoap {
/**
* Gets Information for each WeatherID
*/
@WebResult(name = "GetWeatherInformationResult", targetNamespace = "http://ws.cdyne.com/WeatherWS/")
@RequestWrapper(localName = "GetWeatherInformation", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "weather.GetWeatherInformation")
@WebMethod(operationName = "GetWeatherInformation", action = "http://ws.cdyne.com/WeatherWS/GetWeatherInformation")
@ResponseWrapper(localName = "GetWeatherInformationResponse", targetNamespace = "http://ws.cdyne.com/WeatherWS/", className = "weather.GetWeatherInformationResponse")
public weather.ArrayOfWeatherDescription getWeatherInformation();
...
}
无cxf-rt-frontend-jaxws
依赖
- 进入
getWeatherInformation()
调试导致GetWeatherInformation
( 另一个生成 class. - 进入
GetWeatherInformation
导致com.oracle.webservices.internal.api.message.BasePropertySet
- ...
- 收到来自 SOAP 网络服务的结果。
具有cxf-rt-frontend-jaxws
依赖性
- 进入
getWeatherInformation
而调试导致org.apache.cxf.jaxws.JaxWsClientProxy
(为什么?) - ...
- 抛出异常:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Could not find conduit initiator for address: http://wsf.cdyne.com/WeatherWS/Weather.asmx and transport: http://schemas.xmlsoap.org/soap/http
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:161)
at com.sun.proxy.$Proxy33.getWeatherInformation(Unknown Source)
at weather.WeatherSoap_WeatherSoap_Client.main(WeatherSoap_WeatherSoap_Client.java:49)
Caused by: java.lang.RuntimeException: Could not find conduit initiator for address: http://wsf.cdyne.com/WeatherWS/Weather.asmx and transport: http://schemas.xmlsoap.org/soap/http
at org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:224)
at org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:229)
at org.apache.cxf.endpoint.AbstractConduitSelector.createConduit(AbstractConduitSelector.java:145)
at org.apache.cxf.endpoint.AbstractConduitSelector.getSelectedConduit(AbstractConduitSelector.java:107)
at org.apache.cxf.endpoint.UpfrontConduitSelector.prepare(UpfrontConduitSelector.java:63)
at org.apache.cxf.endpoint.ClientImpl.prepareConduitSelector(ClientImpl.java:853)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:511)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
... 2 more
我知道有针对此异常的解决方法 here 并且它有效。但不适用于我的工作申请。毕竟它会抛出 NPE:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: java.lang.NullPointerException
...
Caused by: org.apache.cxf.binding.soap.SoapFault: java.lang.NullPointerException
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:86)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:52)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:41)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:113)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:802)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1642)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1533)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1336)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:652)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
... 7 more
提问时间
- 为什么即使没有 Apache-CXF 应用程序也能正常工作,为什么还要使用它?
- 在这种情况下是否可以强制应用程序停止使用 Apache-CXF?
我不需要客户端的这种依赖关系(因为没有它们它也能正常工作)。我也只想制作 SOAP。这就是为什么我需要这种依赖关系。我看到的唯一解决方案是将应用程序拆分为单独的消费者和生产者。
application seems to use different implementation of JAX-WS( is it even possible?).
是的。 CXF 有它自己的 jax-ws 提供程序,它的 jar 包含一个声明它的服务文件。 (当 JVM 需要一个 jax-ws 提供者时:它会查看类路径以查看是否声明了一个非默认提供者...并且如果有的话 使用它)。
为什么? 那是 Java 规格:http://docs.oracle.com/javaee/5/api/javax/xml/ws/spi/Provider.html#provider()
Is it possible to force application to stop using Apache-CXF in this case?
是的。在您的类路径上创建适当的资源文件以重定向到默认实现。
详细信息:文件必须在此处:META-INF/services/javax.xml.ws.spi.Provider
(如果您使用 maven:简单地放在此处:/src/main/resources/META-INF/services/javax.xml.ws.spi.Provider
)
并且必须包含一行:
javax.xml.ws.spi.Provider