Andrew Dinn [
http://community.jboss.org/people/adinn] created the discussion
"Latest JBossWS CXF build has broken XTS again"
To view the discussion, visit:
http://community.jboss.org/message/607790#607790
--------------------------------------------------------------
Hi guys,
I have been working on integrating XTS into AS7 trunk and come across a problem in the CXF
release (2.4.0, I believe). It's not a repeat of a previous regression at the code
level but conceptually it is a regression. The specifc problem is detailed below. It
happened because whoever updatd CXF assumed that wenevr you use WSA you must be invoking a
request-reply web service API. That's true as far as the half-baked version of WSA
that Sun incorporated into the JaxWS-WSA JSR is concerned -- the one which removed the
ability to install/detect WSA headers from the API. But it's no good maoing that
assumption in general.
Not only is it quite possible to use WSA with one-way messages in CXF (or, even, in
JBossWS native) it is also, for certain purposes, critical to be able to do this. In
particular, the WSTX standards on which XTS is based requrie one-way messages which use
WSA. So, when a CXF dev adopts this simplifying assumption XTS invariably breaks. This has
happened almost every time the CXF version used by JBossWS has been upgraded. So, as well
as fixing the problem in the current release I think it is important that we get teh CXF
devs to include explicit tests in their tes suite to ensure that it is possible to use WSA
with one way messages.
The specific problem I encountered happens during deployment of an endpoint. I have a war
file, ws-t11-client.war which contains a web,.xml which declares two servlets
. . .
<!-- Client Side Endpoints -->
<servlet>
<servlet-name>CompletionInitiator</servlet-name>
<servlet-class>com.arjuna.webservices11.wsat.sei.CompletionInitiatorPortTypeImpl</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>TerminationParticipant</servlet-name>
<servlet-class>com.arjuna.webservices11.wsarjtx.sei.TerminationParticipantPortTypeImpl</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
. . .
The first class declared in the web.xml is located under WEB-INF/classes and defined as
follows
. . .
@WebService(name = "CompletionInitiatorPortType", targetNamespace = "
http://docs.oasis-open.org/ws-tx/wsat/2006/06
http://docs.oasis-open.org/ws-tx/wsat/2006/06",
serviceName = "CompletionInitiatorService", portName =
"CompletionInitiatorPortType"
)
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@HandlerChain(file="/ws-t_handlers.xml")
@Addressing(required=true)
public class CompletionInitiatorPortTypeImpl
{
@Resource
private WebServiceContext webServiceCtx;
@WebMethod(operationName = "CommittedOperation", action = "
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Committed
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Committed")
@Oneway
@Action(input="
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Committed
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Committed")
public void committedOperation(
@WebParam(name = "Committed", targetNamespace = "
http://docs.oasis-open.org/ws-tx/wsat/2006/06
http://docs.oasis-open.org/ws-tx/wsat/2006/06", partName = "parameters")
Notification parameters)
{
MessageContext ctx = webServiceCtx.getMessageContext();
. . .
}
@WebMethod(operationName = "AbortedOperation", action = "
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Aborted
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Aborted")
@Oneway
@Action(input="
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Aborted
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Aborted")
public void abortedOperation(
@WebParam(name = "Aborted", targetNamespace = "
http://docs.oasis-open.org/ws-tx/wsat/2006/06
http://docs.oasis-open.org/ws-tx/wsat/2006/06", partName = "parameters")
Notification parameters)
{
MessageContext ctx = webServiceCtx.getMessageContext();
. . .
The second class is declared in essentially the same way.
When I deploy the war I get the following output
00:44:38,254 INFO [org.jboss.ws.common.management.DefaultEndpointRegistry] (MSC service
thread 1-4) remove: jboss.ws:context=ws-t11-client,endpoint=CompletionInitiator
00:44:38,256 INFO [org.jboss.ws.common.management.DefaultEndpointRegistry] (MSC service
thread 1-4) remove: jboss.ws:context=ws-t11-client,endpoint=TerminationParticipant
00:44:38,258 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC00001: Failed
to start service jboss.deployment.unit."ws-t11-client.war".INSTALL:
org.jboss.msc.service.StartException in service
jboss.deployment.unit."ws-t11-client.war".INSTALL: Failed to process phase
INSTALL of deployment "ws-t11-client.war"
at
org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:121)
[jboss-as-server-7.0.0.Beta4-SNAPSHOT.jar:7.0.0.Beta4-SNAPSHOT]
at
org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1675)
[jboss-msc-1.0.0.Beta8.jar:1.0.0.Beta8]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
[:1.6.0_21]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[:1.6.0_21]
at java.lang.Thread.run(Thread.java:619) [:1.6.0_21]
Caused by: javax.xml.ws.WebServiceException: java.lang.NullPointerException
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:350)
at org.jboss.wsf.stack.cxf.deployment.EndpointImpl.doPublish(EndpointImpl.java:71)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:239)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:509)
at
org.jboss.wsf.stack.cxf.configuration.NonSpringBusHolder.configure(NonSpringBusHolder.java:113)
at
org.jboss.wsf.stack.cxf.deployment.aspect.BusDeploymentAspect.startDeploymentBus(BusDeploymentAspect.java:109)
at
org.jboss.wsf.stack.cxf.deployment.aspect.BusDeploymentAspect.start(BusDeploymentAspect.java:132)
at
org.jboss.as.webservices.deployers.AspectDeploymentProcessor.internalDeploy(AspectDeploymentProcessor.java:78)
at
org.jboss.as.webservices.deployers.TCCLDeploymentProcessor.deploy(TCCLDeploymentProcessor.java:42)
at
org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:115)
[jboss-as-server-7.0.0.Beta4-SNAPSHOT.jar:7.0.0.Beta4-SNAPSHOT]
... 4 more
Caused by: java.lang.NullPointerException
at
org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildWSAActions(JaxWsServiceFactoryBean.java:547)
at
org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.createOperation(JaxWsServiceFactoryBean.java:620)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createInterface(ReflectionServiceFactoryBean.java:903)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:429)
at
org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:680)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:501)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:241)
at
org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:202)
at
org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:101)
at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:157)
at
org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:192)
at org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:433)
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:322)
... 13 more
The null pointer exception which causes the problem is in the following code taken from
JaxWsServiceFactoryBean.buildWSAActions
Hi guys,
I have been working on integrating XTS into AS7 trunk and come across a problem in the CXF
release (2.4.0, I believe). It's not a repeat of a previous regression at the code
level but conceptually it is a regression. The specifc problem is detailed below. It
happened because whoever updatd CXF assumed that wenevr you use WSA you must be invoking a
request-reply web service API. That's true as far as the half-baked version of WSA
that Sun incorporated into the JaxWS-WSA JSR is concerned -- the one which removed the
ability to install/detect WSA headers from the API. But it's no good maoing that
assumption in general.
Not only is it quite possible to use WSA with one-way messages in CXF (or, even, in
JBossWS native) it is also, for certain purposes, critical to be able to do this. In
particular, the WSTX standards on which XTS is based requrie one-way messages which use
WSA. So, when a CXF dev adopts this simplifying assumption XTS invariably breaks. This has
happened almost every time the CXF version used by JBossWS has been upgraded. So, as well
as fixing the problem in the current release I think it is important that we get teh CXF
devs to include explicit tests in their tes suite to ensure that it is possible to use WSA
with one way messages.
The specific problem I encountered happens during deployment of an endpoint. I have a war
file, ws-t11-client.war which contains a web,.xml which declares two servlets
. . .
<!-- Client Side Endpoints -->
<servlet>
<servlet-name>CompletionInitiator</servlet-name>
<servlet-class>com.arjuna.webservices11.wsat.sei.CompletionInitiatorPortTypeImpl</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>TerminationParticipant</servlet-name>
<servlet-class>com.arjuna.webservices11.wsarjtx.sei.TerminationParticipantPortTypeImpl</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
. . .
The first class declared in the web.xml is located under WEB-INF/classes and defined as
follows
. . .
@WebService(name = "CompletionInitiatorPortType", targetNamespace = "
http://docs.oasis-open.org/ws-tx/wsat/2006/06
http://docs.oasis-open.org/ws-tx/wsat/2006/06",
serviceName = "CompletionInitiatorService", portName =
"CompletionInitiatorPortType"
)
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@HandlerChain(file="/ws-t_handlers.xml")
@Addressing(required=true)
public class CompletionInitiatorPortTypeImpl
{
@Resource
private WebServiceContext webServiceCtx;
@WebMethod(operationName = "CommittedOperation", action = "
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Committed
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Committed")
@Oneway
@Action(input="
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Committed
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Committed")
public void committedOperation(
@WebParam(name = "Committed", targetNamespace = "
http://docs.oasis-open.org/ws-tx/wsat/2006/06
http://docs.oasis-open.org/ws-tx/wsat/2006/06", partName = "parameters")
Notification parameters)
{
MessageContext ctx = webServiceCtx.getMessageContext();
. . .
}
@WebMethod(operationName = "AbortedOperation", action = "
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Aborted
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Aborted")
@Oneway
@Action(input="
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Aborted
http://docs.oasis-open.org/ws-tx/wsat/2006/06/Aborted")
public void abortedOperation(
@WebParam(name = "Aborted", targetNamespace = "
http://docs.oasis-open.org/ws-tx/wsat/2006/06
http://docs.oasis-open.org/ws-tx/wsat/2006/06", partName = "parameters")
Notification parameters)
{
MessageContext ctx = webServiceCtx.getMessageContext();
. . .
The second class is declared in essentially the same way.
When I deploy the war I get the following output
00:44:38,254 INFO [org.jboss.ws.common.management.DefaultEndpointRegistry] (MSC service
thread 1-4) remove: jboss.ws:context=ws-t11-client,endpoint=CompletionInitiator
00:44:38,256 INFO [org.jboss.ws.common.management.DefaultEndpointRegistry] (MSC service
thread 1-4) remove: jboss.ws:context=ws-t11-client,endpoint=TerminationParticipant
00:44:38,258 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC00001: Failed
to start service jboss.deployment.unit."ws-t11-client.war".INSTALL:
org.jboss.msc.service.StartException in service
jboss.deployment.unit."ws-t11-client.war".INSTALL: Failed to process phase
INSTALL of deployment "ws-t11-client.war"
at
org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:121)
[jboss-as-server-7.0.0.Beta4-SNAPSHOT.jar:7.0.0.Beta4-SNAPSHOT]
at
org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1675)
[jboss-msc-1.0.0.Beta8.jar:1.0.0.Beta8]
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
[:1.6.0_21]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[:1.6.0_21]
at java.lang.Thread.run(Thread.java:619) [:1.6.0_21]
Caused by: javax.xml.ws.WebServiceException: java.lang.NullPointerException
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:350)
at org.jboss.wsf.stack.cxf.deployment.EndpointImpl.doPublish(EndpointImpl.java:71)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:239)
at org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:509)
at
org.jboss.wsf.stack.cxf.configuration.NonSpringBusHolder.configure(NonSpringBusHolder.java:113)
at
org.jboss.wsf.stack.cxf.deployment.aspect.BusDeploymentAspect.startDeploymentBus(BusDeploymentAspect.java:109)
at
org.jboss.wsf.stack.cxf.deployment.aspect.BusDeploymentAspect.start(BusDeploymentAspect.java:132)
at
org.jboss.as.webservices.deployers.AspectDeploymentProcessor.internalDeploy(AspectDeploymentProcessor.java:78)
at
org.jboss.as.webservices.deployers.TCCLDeploymentProcessor.deploy(TCCLDeploymentProcessor.java:42)
at
org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:115)
[jboss-as-server-7.0.0.Beta4-SNAPSHOT.jar:7.0.0.Beta4-SNAPSHOT]
... 4 more
Caused by: java.lang.NullPointerException
at
org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildWSAActions(JaxWsServiceFactoryBean.java:547)
at
org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.createOperation(JaxWsServiceFactoryBean.java:620)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createInterface(ReflectionServiceFactoryBean.java:903)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:429)
at
org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:680)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:501)
at
org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:241)
at
org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:202)
at
org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:101)
at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:157)
at
org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:192)
at org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:433)
at org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:322)
... 13 more
The null pointer exception which causes the problem is in the following code taken from
JaxWsServiceFactoryBean.buildWSAActions
. . .
if (action == null && addressing != null) {
operation.getInput().addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME,
inputAction);
operation.getInput().addExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME,
inputAction);
*operation.getOutput().*addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME,
computeAction(operation,
"Response"));
operation.getOutput().addExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME,
computeAction(operation,
"Response"));
} else {
MessageInfo input = operation.getInput();
input.addExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME, inputAction);
if (!StringUtils.isEmpty(action.input())) {
input.addExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME,
inputAction);
}
MessageInfo output = operation.getOutput();
if (output != null && !StringUtils.isEmpty(action.output())) {
output.addExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME,
action.output());
. . .
The offending line is the one in bold. Notice that in the else clause the result of the
getOutput() call is checked ut in the case where addressing is being used it is not
checked. Clearly the code is based on the wrong assumption that code using WSA must be
employing a request-reply exchange.
This needs a CXF JIRA a san umbrella for an underlying CXF JIRA. I suspect that this is
likely to be the first of several problems. It's hard for me to hand over a test case
for you to use at the moment as the XTS code is only integrated into AS7 using string and
glue. Also, I have limited time to get this integration fixed so I need quick turnaround
on a patch here. If you can provide advice on what I need to set up in order to rebuild a
patched version of CXF I will happily continue to push on and debug as far as I can.
regards,
Andrew Dinn
--------------------------------------------------------------
Reply to this message by going to Community
[
http://community.jboss.org/message/607790#607790]
Start a new discussion in JBoss Web Services Development at Community
[
http://community.jboss.org/choose-container!input.jspa?contentType=1&...]