I'm trying out WSDL-first service development with JSR-181 anotations and a stateless bean service, and I'm having some problems controlling some of the finer aspects of WSDL. I'm using jbossws-1.0.1.GA with JBossAS-4.0.4.GA. I'm actually mentoring a company that's planning on using JBossWS for a large Java/.Net integration effort, so easy WSDL-first service development would be really necessary to say the JBossWS component is the one to use.
I have two specific problems described in the remained of this post:
a. The service name and port name in the JBossWS-generated WSDL don't match my original WSDL's service name and port name, and I can't figure out a way to force them to match. Not a big deal really, but if there's a way to match the names I'd like to know.
b. The elementFormDefault for the JBossWS-generated WSDL is "qualified", which does not match the original WSDL's -- the original WSDL does not set the elementFormDefault attribute in its schema, so I suspect the value should be the XML1.0+Namespaces default: "unqualified".
c. JBossWS doesn't seem to be able to handle element namespace and service namespace being different, at least not in this WSDL-first test case. JBossWS unmarsalling seems to prefer to use the WSDL targetNamespace instead of its nested schema's targetNamespace for elements when the two namespaces are different.
----- Service Name and Port Name -----
I'm starting with the WSDL given below as "InitialHelloWorld.wsdl", which defines a pretty simple HelloWorld service. This service defines:
1. A single operation named "sayHello", with an input message element with name tns:SayHelloRequest and an output message response element named tns:SayHelloResponse.
2. A port type named tns:Hello_PortType, consisting of just the single operation.
3. A binding named tns:Hello_PortBinding consisting of just a doc/lit binding of Hello_PortType.
4. A service named tns:Hello_Service consisting of a port named tns:Hello_Port which references the binding.
To implement the service described by this WSDL I first ran the original WSDL through the JAX-WS 2.0 RI's wsimport tool to generate JAXB types and the SEI representing Hello_PortType.
Note that the names of the operations messages requires use of BARE encoding in the SEI. This is the only way using JSR-181 annotations to meet the WSDL's definition of the message element names (since they don't conform to the JAX-WS mapping of method names to message element names).
OK, so I have an SEI, and its now properly annotated to match the input WSDL. However, I now don't have a way to implement the service so that the JBossWS-generated WSDL with have service name or port name matching the original WSDL ("Hello_Service" and "Hello_Port", respectively). At least I can't figure out a way to influence either of these names in the generated WSDL using JSR-181 annotations.
Anyone know of a JSR-181 "pure" way to force the generated WSDL to match my requirements? Or any JBossWS-specific way?
----- Element Form Default Mismatch -----
After implementing a web service class and serving it up in JBossWS, the JBossWS-generated WSDL specifically uses an elementFormDefault="qualified" value in the schemas. I'm pretty sure the original WSDL is using a value of "unqualified", so there's a mismatch here.
Actually, the original WSDL's does not specify an elementFormDefault value. So the (erm) "default elementFormDefault" value should be "unqualified".
I'm pretty sure the JBossWS is incorrectly requiring a qualified element form -- when I tweak the original WSDL to force qualified elements, then everything works fine. But forcing to use unqualified elements also fails -- the runtime error indicates that the unmarshalling fails because the server is expecting an element name qualified by the WSDL targetNamespace (I don't think this should not be the case).
Am I wrong here or is this somnething that should be entered in to JIRA?
----- WSDL and Schema namespace differences -----
Having either unqualified element names or having elements with a namespace different than the WSDL targetNamespace does not seem to be digested well with JBossWS. For example, the WSDL below OriginalHelloService.wsdl has two different namespaces, one for the WSDL and one for the embedded schema. When trying to communicate with a service implemented to the SEI genearted from this WSDL, I receive UnmarshalExceptions. The error message indicates that the qualifed element name expected by the unmarshaller has the WSDL namespace, not the schema namespace, which I think is not what should be happenning.
Am I wrong here, or should this be entered in JIRA?
<!-- OriginalHelloWorld.wsdl --> <definitions name="HelloService" targetNamespace="http://www.cardinal.com/HelloWorld.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns-ws="http://www.cardinal.com/HelloWorld.wsdl" xmlns:tns-xsd="http://www.cardinal.com/HelloWorld.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <types> <xsd:schema targetNamespace="http://www.cardinal.com/HelloWorld.xsd"> <xsd:element name="SayHelloRequest"> <xsd:complexType> <xsd:sequence> <xsd:element name="firstName" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="SayHelloResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="greeting" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </types> <message name="SayHelloRequest"> <part name="SayHelloRequest" element="tns-xsd:SayHelloRequest"/> </message> <message name="SayHelloResponse"> <part name="SayHelloResponse" element="tns-xsd:SayHelloResponse"/> </message> <portType name="Hello_PortType"> <operation name="sayHello"> <input message="tns-ws:SayHelloRequest"/> <output message="tns-ws:SayHelloResponse"/> </operation> </portType> <binding name="Hello_Binding" type="tns-ws:Hello_PortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sayHello"> <soap:operation soapAction="" style="document"/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> <service name="Hello_Service"> <documentation>WSDL File for HelloService</documentation> <port binding="tns-ws:Hello_Binding" name="Hello_Port"> <soap:address location="http://localhost:8080/Hello/HelloWebServiceImpl"/> </port> </service> </definitions>