XFire

WSDL tatget namespace incorrectly used in message serialisation

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.1.2, 1.2-RC, 1.2
  • Fix Version/s: 1.2
  • Component/s: Core
  • Labels:
    None
  • Environment:
    Windows XP/Java 5.0
  • Number of attachments :
    1

Description

For a fairly simple project, starting with a WSDL and using wsgen etc to create a service, we find that a .NET client is unable to deserialise the response message. Inspection of the message leads us to believe that the messages are being serialised incorrectly. The first element below the soap:Body is being put in the namespace of the WSDL, rather than the namespace of the schema element. The generated WSDL that XFire displays through the Web-app also displays a similar issue, creating an additonal schema where only existed in the original WSDL.

I have attached a sample project that, when used with a 'sniffer' demonstrates this.

Activity

Hide
Paul Downey added a comment -

http://www.w3.org/TR/2001/NOTE-wsdl-20010315#_soap:body

"""
If use is literal, then each part references a concrete schema
definition using either the element or type attribute. In the first
case, the element referenced by the part will appear directly
under the Body element (for document style bindings)...
"""

for concrete, we read "the qname specified by the schema",
this is how other toolkits work.

Paul

Show
Paul Downey added a comment - http://www.w3.org/TR/2001/NOTE-wsdl-20010315#_soap:body """ If use is literal, then each part references a concrete schema definition using either the element or type attribute. In the first case, the element referenced by the part will appear directly under the Body element (for document style bindings)... """ for concrete, we read "the qname specified by the schema", this is how other toolkits work. Paul
Hide
Dan Diephouse added a comment -

Thanks for the TestCase. Scheduling this for 1.2 as it seems critical and investigating it now.

Show
Dan Diephouse added a comment - Thanks for the TestCase. Scheduling this for 1.2 as it seems critical and investigating it now.
Hide
Paul Downey added a comment -

Thanks Dan, it's a show-stopper for WSDL first development. Further evidence that the schema targetNamespace is the right thing to use comes from the WS-I Basic Profile:

"""
WSDL 1.1 is not completely clear what, in document-literal style bindings,
the child element of soap:Body is.

R2712 A document-literal binding MUST be serialized as an ENVELOPE with
a soap:Body whose child element is an instance of the global element declaration
referenced by the corresponding wsdl:message part.
"""

"""
In a document-literal SOAP binding, the serialized element child of the soap:Body
gets its namespace from the targetNamespace of the schema that defines the element.
"""

http://www.ws-i.org/Profiles/BasicProfile-1.1.html#Namespaces_for_soapbind_Elements
http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html#Child_Element_for_Document-Literal_Bindings

Show
Paul Downey added a comment - Thanks Dan, it's a show-stopper for WSDL first development. Further evidence that the schema targetNamespace is the right thing to use comes from the WS-I Basic Profile: """ WSDL 1.1 is not completely clear what, in document-literal style bindings, the child element of soap:Body is. R2712 A document-literal binding MUST be serialized as an ENVELOPE with a soap:Body whose child element is an instance of the global element declaration referenced by the corresponding wsdl:message part. """ """ In a document-literal SOAP binding, the serialized element child of the soap:Body gets its namespace from the targetNamespace of the schema that defines the element. """ http://www.ws-i.org/Profiles/BasicProfile-1.1.html#Namespaces_for_soapbind_Elements http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html#Child_Element_for_Document-Literal_Bindings
Hide
Dan Diephouse added a comment -

OK, I found the bug. Working on determing the correct fix. I'll think I can get a fix in tonight and push out some new snapshots.

Show
Dan Diephouse added a comment - OK, I found the bug. Working on determing the correct fix. I'll think I can get a fix in tonight and push out some new snapshots.
Hide
Dan Diephouse added a comment -

A fix is now in SVN. I'll post a SNAPSHOT build later tonight and send you a link.

Show
Dan Diephouse added a comment - A fix is now in SVN. I'll post a SNAPSHOT build later tonight and send you a link.
Hide
Adrian Smith added a comment -

Dan,

I have tried out this new jar file with only partial success.

1 The generated WSDL now has only one schema which is good, but the schema targetNamespace is not the same as the original WSDL.
2. The messages on the wire seem unchanged:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<makeCallResponse xmlns="http://test.bt.com/2006/08/Service">
<status xmlns="http://test.bt.com/2006/08/Service/Schema">Hello Adrian SmithDotNet</status>
</makeCallResponse>
</soap:Body>
</soap:Envelope>

Notice that the makeCallResponse element is still in the WSDL namespace rather than the schema namespace. The sample .NET client still fails to deserialise correctly.

Regards,

Adrian

Show
Adrian Smith added a comment - Dan, I have tried out this new jar file with only partial success. 1 The generated WSDL now has only one schema which is good, but the schema targetNamespace is not the same as the original WSDL. 2. The messages on the wire seem unchanged: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Body> <makeCallResponse xmlns="http://test.bt.com/2006/08/Service"> <status xmlns="http://test.bt.com/2006/08/Service/Schema">Hello Adrian SmithDotNet</status> </makeCallResponse> </soap:Body> </soap:Envelope> Notice that the makeCallResponse element is still in the WSDL namespace rather than the schema namespace. The sample .NET client still fails to deserialise correctly. Regards, Adrian
Hide
Adrian Smith added a comment -

Can we re-open this one please?

Show
Adrian Smith added a comment - Can we re-open this one please?
Hide
Dan Diephouse added a comment -

OK, looking into this. Thanks

Show
Dan Diephouse added a comment - OK, looking into this. Thanks
Hide
Dan Diephouse added a comment -

Just wanted to give you a heads up I'm still on this. Sorry for the delay. It requires a change to our generator module. The issue is that JSR181 annotations don't carry the necessary metadata for this wsdl. However, JAX-WS does, so that is one option. There might be a non-jax-ws option as well. I'm looking into it.

Show
Dan Diephouse added a comment - Just wanted to give you a heads up I'm still on this. Sorry for the delay. It requires a change to our generator module. The issue is that JSR181 annotations don't carry the necessary metadata for this wsdl. However, JAX-WS does, so that is one option. There might be a non-jax-ws option as well. I'm looking into it.
Hide
Dan Diephouse added a comment -

OK, I've fixed this - and I even wrote the test correctly this time!

The new build is here:

http://snapshots.repository.codehaus.org/org/codehaus/xfire/xfire-all/1.2-SNAPSHOT/xfire-all-1.2-20060824.185250-9.jar

You'll need to use the JAXWS profile to generate your client like so:

<wsgen outputDirectory="${basedir}/target/test-services"
wsdl="${basedir}/src/wsdl/echo.wsdl"
package="com.acme.echo"
profile="org.codehaus.xfire.jaxws.gen.JAXWSProfile"/>

If you're writing a server implementation of the service, you'll need to use the JAXWSServiceFactory to create your service, instead of the AnnotationServiceFactory.

Show
Dan Diephouse added a comment - OK, I've fixed this - and I even wrote the test correctly this time! The new build is here: http://snapshots.repository.codehaus.org/org/codehaus/xfire/xfire-all/1.2-SNAPSHOT/xfire-all-1.2-20060824.185250-9.jar You'll need to use the JAXWS profile to generate your client like so: <wsgen outputDirectory="${basedir}/target/test-services" wsdl="${basedir}/src/wsdl/echo.wsdl" package="com.acme.echo" profile="org.codehaus.xfire.jaxws.gen.JAXWSProfile"/> If you're writing a server implementation of the service, you'll need to use the JAXWSServiceFactory to create your service, instead of the AnnotationServiceFactory.
Hide
Alex Fishlock added a comment -

Does this prevent an annotated webservice from functioning then?

Show
Alex Fishlock added a comment - Does this prevent an annotated webservice from functioning then?
Hide
Dan Diephouse added a comment -

No, JAXWSServiceFactory just extends AnnotationServiceFactory. It supports some additional (necessary) JAX-WS annotations that the JSR181 people didn't think to include. Think of it as JSR181+MoreAnnotations

Show
Dan Diephouse added a comment - No, JAXWSServiceFactory just extends AnnotationServiceFactory. It supports some additional (necessary) JAX-WS annotations that the JSR181 people didn't think to include. Think of it as JSR181+MoreAnnotations
Hide
Andrew Ochsner added a comment -

So I've tried this on my wsdl and get NullPointerExceptions on webservice calls that have no parameters.

So for this example, if you change makeCall request to:

<xs:element name="makeCall">
<xs:complexType />
</xs:element>

You get a stack trace that looks like this:
2006-08-31 15:42:44,722 ERROR [DefaultFaultHandler][][][] - Fault occurred! java.lang.NullPointerException
at org.codehaus.xfire.jaxws.JAXWSOperationBinding.readMessage(JAXWSOperationBinding.java:141)
at org.codehaus.xfire.jaxws.JAXWSBinding.readMessage(JAXWSBinding.java:55)
at org.codehaus.xfire.soap.handler.SoapBodyHandler.invoke(SoapBodyHandler.java:42)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
at org.codehaus.xfire.transport.DefaultEndpoint.onReceive(DefaultEndpoint.java:64)
at org.codehaus.xfire.transport.AbstractChannel.receive(AbstractChannel.java:38)
at org.codehaus.xfire.transport.http.XFireServletController.invoke(XFireServletController.java:279)
at org.codehaus.xfire.transport.http.XFireServletController.doService(XFireServletController.java:121)
at org.codehaus.xfire.transport.http.XFireServlet.doPost(XFireServlet.java:116)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
at java.lang.Thread.run(Thread.java:595)

Can you have a look at this and re-open if you can reproduce?

Thanks
Andy O

Show
Andrew Ochsner added a comment - So I've tried this on my wsdl and get NullPointerExceptions on webservice calls that have no parameters. So for this example, if you change makeCall request to: <xs:element name="makeCall"> <xs:complexType /> </xs:element> You get a stack trace that looks like this: 2006-08-31 15:42:44,722 ERROR [DefaultFaultHandler][][][] - Fault occurred! java.lang.NullPointerException at org.codehaus.xfire.jaxws.JAXWSOperationBinding.readMessage(JAXWSOperationBinding.java:141) at org.codehaus.xfire.jaxws.JAXWSBinding.readMessage(JAXWSBinding.java:55) at org.codehaus.xfire.soap.handler.SoapBodyHandler.invoke(SoapBodyHandler.java:42) at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131) at org.codehaus.xfire.transport.DefaultEndpoint.onReceive(DefaultEndpoint.java:64) at org.codehaus.xfire.transport.AbstractChannel.receive(AbstractChannel.java:38) at org.codehaus.xfire.transport.http.XFireServletController.invoke(XFireServletController.java:279) at org.codehaus.xfire.transport.http.XFireServletController.doService(XFireServletController.java:121) at org.codehaus.xfire.transport.http.XFireServlet.doPost(XFireServlet.java:116) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at javax.servlet.http.HttpServlet.service(HttpServlet.java:810) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178) at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175) at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869) at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527) at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112) at java.lang.Thread.run(Thread.java:595) Can you have a look at this and re-open if you can reproduce? Thanks Andy O
Hide
Dan Diephouse added a comment -

Reopening again for 1.2.1

Show
Dan Diephouse added a comment - Reopening again for 1.2.1
Hide
Dan Diephouse added a comment -

Hiya, I added a test for this to SVN and I can't reproduce it. Its really weird that you're getting an NPE right there. At the very least it doesn't have anything to do with the targetNamespace. I would check to make sure that your client is generated using the latest WSDL.

If you're still having problems, please open a new issue. Also, a test WSDL & test case would help greatly.

Show
Dan Diephouse added a comment - Hiya, I added a test for this to SVN and I can't reproduce it. Its really weird that you're getting an NPE right there. At the very least it doesn't have anything to do with the targetNamespace. I would check to make sure that your client is generated using the latest WSDL. If you're still having problems, please open a new issue. Also, a test WSDL & test case would help greatly.
Hide
Adrian Smith added a comment -

I have managed to generate the code for this using wsgen but still have issues:

1. The original problem still exists, see above (way up there!)
2. There is now no client class generated. I can use the service stub as a client stub, but there seems no way of overiding the endpoint URI. This is a MUST.
3. I feel that I shouldn't have to provide special parameters to the wsgen to make this simple service work correctly? It should just work!

Please re-open this case. This issue is really a show stopper for WSDL-first development.

Show
Adrian Smith added a comment - I have managed to generate the code for this using wsgen but still have issues: 1. The original problem still exists, see above (way up there!) 2. There is now no client class generated. I can use the service stub as a client stub, but there seems no way of overiding the endpoint URI. This is a MUST. 3. I feel that I shouldn't have to provide special parameters to the wsgen to make this simple service work correctly? It should just work! Please re-open this case. This issue is really a show stopper for WSDL-first development.
Hide
Dan Diephouse added a comment -

Hi Adrian,

I'm sorry you're still experiencing issues. Regarding #1: I'm a bit confused though as I have a unit test with the wsdl you've provided showing that it works.

Your wsdl:
http://svn.xfire.codehaus.org/browse/xfire/trunk/xfire/xfire-jaxws/src/wsdl/XFire582.wsdl?r=1836

The test input message:
http://svn.xfire.codehaus.org/browse/xfire/trunk/xfire/xfire-jaxws/src/test/org/codehaus/xfire/x582/callmessage.xml?r=1836

The test (see line 57 which sends the message and then asserts that the correct response has been received:
http://svn.xfire.codehaus.org/browse/xfire/trunk/xfire/xfire-jaxws/src/test/org/codehaus/xfire/x582/XFire582Test.java?r=1836#l57

So I'm not sure why you're getting back the wrong response. Are you per chance using the AnnotationServiceFactory instead of the JAXWSServiceFactory?

Regarding #2:

XFireNamespaceProblemServiceService stub = new XFireNamespaceProblemServiceService();
XFireNamespaceProblemInterface client = stub.getXFireNamespaceProblemServiceLocalPort();

Client xfireClient = Client.getInstance(client);
xfireClient.setURL("http://myurl");

client.makeCall()

#3 Yes, you're absolutely right. Which is why in the next version, JSR181 by itself will be completely deprecated. When XFire started, JAX-WS wasn't finalized, so we had to use JSR181. It wasn't until 1.1 that JAX-WS was finalized.

Show
Dan Diephouse added a comment - Hi Adrian, I'm sorry you're still experiencing issues. Regarding #1: I'm a bit confused though as I have a unit test with the wsdl you've provided showing that it works. Your wsdl: http://svn.xfire.codehaus.org/browse/xfire/trunk/xfire/xfire-jaxws/src/wsdl/XFire582.wsdl?r=1836 The test input message: http://svn.xfire.codehaus.org/browse/xfire/trunk/xfire/xfire-jaxws/src/test/org/codehaus/xfire/x582/callmessage.xml?r=1836 The test (see line 57 which sends the message and then asserts that the correct response has been received: http://svn.xfire.codehaus.org/browse/xfire/trunk/xfire/xfire-jaxws/src/test/org/codehaus/xfire/x582/XFire582Test.java?r=1836#l57 So I'm not sure why you're getting back the wrong response. Are you per chance using the AnnotationServiceFactory instead of the JAXWSServiceFactory? Regarding #2: XFireNamespaceProblemServiceService stub = new XFireNamespaceProblemServiceService(); XFireNamespaceProblemInterface client = stub.getXFireNamespaceProblemServiceLocalPort(); Client xfireClient = Client.getInstance(client); xfireClient.setURL("http://myurl"); client.makeCall() #3 Yes, you're absolutely right. Which is why in the next version, JSR181 by itself will be completely deprecated. When XFire started, JAX-WS wasn't finalized, so we had to use JSR181. It wasn't until 1.1 that JAX-WS was finalized.
Hide
Adrian Smith added a comment -

Dan,

Thanks for the tips. I have now changed by services.xml to include <serviceFactory>org.codehaus.xfire.jaxws.JAXWSServiceFactory</serviceFactory>
and it now works as expected. Thanks.

Is this change in the current release 1.2 ?

Regards,

Adrian

Show
Adrian Smith added a comment - Dan, Thanks for the tips. I have now changed by services.xml to include <serviceFactory>org.codehaus.xfire.jaxws.JAXWSServiceFactory</serviceFactory> and it now works as expected. Thanks. Is this change in the current release 1.2 ? Regards, Adrian
Hide
Dan Diephouse added a comment -

It should be. There are a few JAX-WS fixes coming out in 1.2.1 very soon though. Mostly around fault generation compliance. 1.2.1 should be out possibly tonight or otherwise tomorrow morning. I'm waiting to hear back about a specific fix from a build before its released.

Show
Dan Diephouse added a comment - It should be. There are a few JAX-WS fixes coming out in 1.2.1 very soon though. Mostly around fault generation compliance. 1.2.1 should be out possibly tonight or otherwise tomorrow morning. I'm waiting to hear back about a specific fix from a build before its released.

People

Vote (2)
Watch (3)

Dates

  • Created:
    Updated:
    Resolved: