Namespace problems invoking document/literal web service
moebus Jun 17, 2005 4:38 AMHave created a hello world web service in .NET and want to call it from JBoss 4.0.2 on j2se1.4.2.
I have encountered following problem:
org.xml.sax.SAXException: Invalid element in (packagename).HelloWorldResponse - HelloWorldResult
After looking around a bit in the code I found a place where I could fix this, it is in the class
TypeMappingDescription.initMetaDataFromJavaXMLTypeMapping(),
where the xmlName as written into the elementDesc tag, insert
xmlName = qname.getPrefix() + ":" + xmlName;
Have already looked through the CVS versions for this file and found that some weeks ago this change was put in and out of this class several times, and is now out in the release version.
May be I need to have other axis or xml parser class changes since it seems that the sax parser reads this element (HelloWorldResult) with the implied namespace.
The wsdl is as follows:
<?xml version="1.0" encoding="utf-8"?> <wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://tempuri.org/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <wsdl:types> <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/"> <s:element name="HelloWorld"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="name" type="s:string" /> </s:sequence> </s:complexType> </s:element> <s:element name="HelloWorldResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string" /> </s:sequence> </s:complexType> </s:element> </s:schema> </wsdl:types> <wsdl:message name="HelloWorldSoapIn"> <wsdl:part name="parameters" element="tns:HelloWorld" /> </wsdl:message> <wsdl:message name="HelloWorldSoapOut"> <wsdl:part name="parameters" element="tns:HelloWorldResponse" /> </wsdl:message> <wsdl:portType name="Service1Soap"> <wsdl:operation name="HelloWorld"> <wsdl:input message="tns:HelloWorldSoapIn" /> <wsdl:output message="tns:HelloWorldSoapOut" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="Service1Soap" type="tns:Service1Soap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> <wsdl:operation name="HelloWorld"> <soap:operation soapAction="http://tempuri.org/HelloWorld" style="document" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="Service1"> <wsdl:port name="Service1Soap" binding="tns:Service1Soap"> <soap:address location="http://localhost/MMDotNetTest/Service1.asmx" /> </wsdl:port> </wsdl:service>
Then I ran wscompile from jwsdp-1.5, with:
wscompile -gen:client -f:documentliteral -f:wsi -mapping jaxrpc-test.xml -keep config-client.xml
which produces among other stuff the mapping file and client classes.
the jaxrpc-test.xml file reads
<?xml version="1.0" encoding="UTF-8"?> <java-wsdl-mapping version="1.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://www.ibm.com/webservices/xsd/j2ee_jaxrpc_mapping_1_1.xsd"> <package-mapping> <package-type>de.aeb.mm.testwebservice.dotnetJboss</package-type> <namespaceURI>http://tempuri.org/</namespaceURI> </package-mapping> <java-xml-type-mapping> <java-type>de.aeb.mm.testwebservice.dotnetJboss.HelloWorld</java-type> <anonymous-type-qname>http://tempuri.org/:>HelloWorld</anonymous-type-qname> <qname-scope>complexType</qname-scope> <variable-mapping> <java-variable-name>name</java-variable-name> <xml-element-name>name</xml-element-name> </variable-mapping> </java-xml-type-mapping> <java-xml-type-mapping> <java-type>de.aeb.mm.testwebservice.dotnetJboss.HelloWorldResponse</java-type> <anonymous-type-qname>http://tempuri.org/:>HelloWorldResponse</anonymous-type-qname> <qname-scope>complexType</qname-scope> <variable-mapping> <java-variable-name>helloWorldResult</java-variable-name> <xml-element-name>HelloWorldResult</xml-element-name> </variable-mapping> </java-xml-type-mapping> <service-interface-mapping> <service-interface>de.aeb.mm.testwebservice.dotnetJboss.Service1</service-interface> <wsdl-service-name xmlns:serviceNS="http://tempuri.org/">serviceNS:Service1</wsdl-service-name> <port-mapping> <port-name>Service1Soap</port-name> <java-port-name>Service1Soap</java-port-name> </port-mapping> </service-interface-mapping> <service-endpoint-interface-mapping> <service-endpoint-interface>de.aeb.mm.testwebservice.dotnetJboss.Service1Soap</service-endpoint-interface> <wsdl-port-type xmlns:portTypeNS="http://tempuri.org/">portTypeNS:Service1Soap</wsdl-port-type> <wsdl-binding xmlns:bindingNS="http://tempuri.org/">bindingNS:Service1Soap</wsdl-binding> <service-endpoint-method-mapping> <java-method-name>helloWorld</java-method-name> <wsdl-operation>HelloWorld</wsdl-operation> <method-param-parts-mapping> <param-position>0</param-position> <param-type>de.aeb.mm.testwebservice.dotnetJboss.HelloWorld</param-type> <wsdl-message-mapping> <wsdl-message xmlns:wsdlMsgNS="http://tempuri.org/">wsdlMsgNS:HelloWorldSoapIn</wsdl-message> <wsdl-message-part-name>parameters</wsdl-message-part-name> <parameter-mode>IN</parameter-mode> </wsdl-message-mapping> </method-param-parts-mapping> <wsdl-return-value-mapping> <method-return-value>de.aeb.mm.testwebservice.dotnetJboss.HelloWorldResponse</method-return-value> <wsdl-message xmlns:wsdlMsgNS="http://tempuri.org/">wsdlMsgNS:HelloWorldSoapOut</wsdl-message> <wsdl-message-part-name>parameters</wsdl-message-part-name> </wsdl-return-value-mapping> </service-endpoint-method-mapping> </service-endpoint-interface-mapping> </java-wsdl-mapping>
The service interface class is as follows (omitting lengthy package names that wscompile writes into every parameter)
public interface Service1Soap extends java.rmi.Remote { public HelloWorldResponse helloWorld(HelloWorld parameters) throws java.rmi.RemoteException; }
I invoke this with the following client code
String name = "Joe"; HelloWorld requestArg = new HelloWorld(); requestArg.setName(name); try { ServiceFactory factory = ServiceFactory.newInstance(); ServiceFactoryImpl jbossFactory = (ServiceFactoryImpl)factory; Service service = jbossFactory.createService( new URL("http://localhost/MMDotNetTest/Service1.asmx?WSDL"), new URL("http://localhost/jboss-test/jaxrpc-test.xml"), null, new QName("http://tempuri.org/", "Service1"), null); Service1Soap serviceSoap = (Service1Soap)service.getPort(new QName("http://tempuri.org/", "Service1Soap") ,Service1Soap.class); HelloWorldResponse res = serviceSoap.helloWorld(requestArg); System.out.println(res.getHelloWorldResult()); } catch (Exception e2) { e2.printStackTrace(); }
Just to give all information, a sample answer as sent over the wire is as follows:
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <HelloWorldResponse xmlns="http://tempuri.org/"> <HelloWorldResult> Hello Joe, here is .NET </HelloWorldResult> </HelloWorldResponse> </soap:Body> </soap:Envelope>
b.t.w. the SAX exception is then converted in an UndeclaredThrowableException since the helloWorld() method is declared to only throw RemoteExceptions. so this might also need some fix.