12 Replies Latest reply on Sep 11, 2007 8:00 PM by vashistvishal

    JBoss wstool generate incorrect WSDL file

    mendaye

      Hello All:

      I am using JBOSS 4.0.4 to do web services development. I have created WSDL and all other XML file for my EJB end-point using JBoss wstool. I have successfully deployed and tested this Web Service. However, it worked fine when the rutun type of the methods are Java primitave types. For some reason it doesn't work for Java Collection type (ArrayList, Hashtable, Hashmap) - I get exception from JBoss Server "XML document structures must start and end within the same entity" - I look deep into WSDL file, it seems the complex data type generated for these collection classes and custom object is wrong. I have attached the code, WSDL and other XML file. I am not sure if I miss something here. Please help!!!

      JBoss ant task

      <taskdef name="wstools" classname="org.jboss.ws.tools.ant.wstools">
       <classpath refid="base.libraries"/>
       <classpath refid="client.classpath"/>
       <classpath path="${api.classpath.dir}"/>
       <classpath path="${db.classpath.dir}"/>
       <!-- <classpath path="${util.classpath.dir}"/> -->
       </taskdef>
      <wstools dest="${dest.dir}" config="${cnfg.dir}/wstools-config.xml"/>
      


      wstools-config.xml file
      
      <?xml version="1.0" encoding="UTF-8"?>
      <configuration
       xmlns="http://www.jboss.org/jbossws-tools"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation=
       "http://www.jboss.org/jbossws-tools
       http://www.jboss.org/jbossws-tools/schema/jbossws-tool_1_0.xsd">
       <java-wsdl>
       <service name="PVNGDeviceService" style="document"
       endpoint="com.panduit.pvng.service.api.db.interfaces.DeviceEndpoint"/>
       <namespaces
       target-namespace="http://db.panduit.com/dbaccess"
       type-namespace="http://db.panduit.com/dbaccess/types"/>
       <mapping file="jaxrpc-mapping.xml"/>
       <webservices ejb-link="PVNGDevice"/>
       </java-wsdl>
      </configuration>
      
      


      Generated WSDL file - Please look at the bold part for complex data type.


      <?xml version="1.0" encoding="UTF-8"?>
      <definitions name='PVNGDeviceService' targetNamespace='http://db.panduit.com/dbaccess' xmlns='http://schemas.xmlsoap.org/wsdl/' xmlns:ns1='http://db.panduit.com/dbaccess/types' xmlns:ns2='http://util.java/jaws' xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:tns='http://db.panduit.com/dbaccess' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
       <types>
       <schema targetNamespace='http://db.panduit.com/dbaccess/types' xmlns='http://www.w3.org/2001/XMLSchema' xmlns:ns2='http://util.java/jaws' xmlns:soap11-enc='http://schemas.xmlsoap.org/soap/encoding/' xmlns:tns='http://db.panduit.com/dbaccess/types' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
       <import namespace='http://util.java/jaws'/>
       <complexType name='getAllHashValues'>
       <sequence>
       <element name='String_1' nillable='true' type='string'/>
       </sequence>
       </complexType>
       <complexType name='getAllHashValuesResponse'>
       <sequence>
       <element name='result' nillable='true' type='ns2:Hashtable'/>
       </sequence>
       </complexType>
       <complexType name='getAllNames'>
       <sequence>
       <element name='String_1' nillable='true' type='string'/>
       </sequence>
       </complexType>
       <complexType name='getAllNamesResponse'>
       <sequence>
       <element name='result' nillable='true' type='ns2:Vector'/>
       </sequence>
       </complexType>
       <complexType name='getAllValues'>
       <sequence>
       <element name='String_1' nillable='true' type='string'/>
       </sequence>
       </complexType>
       <complexType name='getAllValuesResponse'>
       <sequence>
       <element name='result' nillable='true' type='ns2:HashMap'/>
       </sequence>
       </complexType>
       <complexType name='PVNGAPIException'>
       <sequence>
       <element name='errorMessage' nillable='true' type='string'/>
       <element name='methodName' nillable='true' type='string'/>
       </sequence>
       </complexType>
       <complexType name='getNames'>
       <sequence/>
       </complexType>
       <complexType name='getNamesResponse'>
       <sequence>
       <element name='result' nillable='true' type='ns2:ArrayList'/>
       </sequence>
       </complexType>
       <element name='getAllHashValues' type='tns:getAllHashValues'/>
       <element name='getAllHashValuesResponse' type='tns:getAllHashValuesResponse'/>
       <element name='getAllNames' type='tns:getAllNames'/>
       <element name='getAllNamesResponse' type='tns:getAllNamesResponse'/>
       <element name='getAllValues' type='tns:getAllValues'/>
       <element name='getAllValuesResponse' type='tns:getAllValuesResponse'/>
       <element name='PVNGAPIException' type='tns:PVNGAPIException'/>
       <element name='getNames' type='tns:getNames'/>
       <element name='getNamesResponse' type='tns:getNamesResponse'/>
       </schema>
       <schema targetNamespace='http://util.java/jaws' xmlns='http://www.w3.org/2001/XMLSchema' xmlns:ns1='http://db.panduit.com/dbaccess/types' xmlns:soap11-enc='http://schemas.xmlsoap.org/soap/encoding/' xmlns:tns='http://util.java/jaws' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
       <import namespace='http://db.panduit.com/dbaccess/types'/>
       <complexType name='ArrayList'>
       <sequence>
       <element name='empty' type='boolean'/>
       </sequence>
       </complexType>
       <complexType name='HashMap'>
       <sequence>
       <element name='empty' type='boolean'/>
       </sequence>
       </complexType>
       <complexType name='Hashtable'>
       <sequence>
       <element name='empty' type='boolean'/>
       </sequence>
       </complexType>
       <complexType name='Vector'>
       <sequence>
       <element name='empty' type='boolean'/>
       <element name='size' type='int'/>
       </sequence>
       </complexType>
       </schema>
       </types>
       <message name='DeviceEndpoint_getAllHashValues'>
       <part element='ns1:getAllHashValues' name='parameters'/>
       </message>
       <message name='DeviceEndpoint_getAllHashValuesResponse'>
       <part element='ns1:getAllHashValuesResponse' name='result'/>
       </message>
       <message name='PVNGAPIException'>
       <part element='ns1:PVNGAPIException' name='PVNGAPIException'/>
       </message>
       <message name='DeviceEndpoint_getAllNames'>
       <part element='ns1:getAllNames' name='parameters'/>
       </message>
       <message name='DeviceEndpoint_getAllNamesResponse'>
       <part element='ns1:getAllNamesResponse' name='result'/>
       </message>
       <message name='DeviceEndpoint_getAllValues'>
       <part element='ns1:getAllValues' name='parameters'/>
       </message>
       <message name='DeviceEndpoint_getAllValuesResponse'>
       <part element='ns1:getAllValuesResponse' name='result'/>
       </message>
       <message name='DeviceEndpoint_getNames'>
       <part element='ns1:getNames' name='parameters'/>
       </message>
       <message name='DeviceEndpoint_getNamesResponse'>
       <part element='ns1:getNamesResponse' name='result'/>
       </message>
       <portType name='DeviceEndpoint'>
       <operation name='getAllHashValues'>
       <input message='tns:DeviceEndpoint_getAllHashValues'/>
       <output message='tns:DeviceEndpoint_getAllHashValuesResponse'/>
       <fault message='tns:PVNGAPIException' name='PVNGAPIException'/>
       </operation>
       <operation name='getAllNames'>
       <input message='tns:DeviceEndpoint_getAllNames'/>
       <output message='tns:DeviceEndpoint_getAllNamesResponse'/>
       <fault message='tns:PVNGAPIException' name='PVNGAPIException'/>
       </operation>
       <operation name='getAllValues'>
       <input message='tns:DeviceEndpoint_getAllValues'/>
       <output message='tns:DeviceEndpoint_getAllValuesResponse'/>
       <fault message='tns:PVNGAPIException' name='PVNGAPIException'/>
       </operation>
       <operation name='getNames'>
       <input message='tns:DeviceEndpoint_getNames'/>
       <output message='tns:DeviceEndpoint_getNamesResponse'/>
       <fault message='tns:PVNGAPIException' name='PVNGAPIException'/>
       </operation>
       </portType>
       <binding name='DeviceEndpointBinding' type='tns:DeviceEndpoint'>
       <soap:binding style='document' transport='http://schemas.xmlsoap.org/soap/http'/>
       <operation name='getAllHashValues'>
       <soap:operation soapAction=''/>
       <input>
       <soap:body use='literal'/>
       </input>
       <output>
       <soap:body use='literal'/>
       </output>
       <fault name='PVNGAPIException'>
       <soap:fault name='PVNGAPIException' use='literal'/>
       </fault>
       </operation>
       <operation name='getAllNames'>
       <soap:operation soapAction=''/>
       <input>
       <soap:body use='literal'/>
       </input>
       <output>
       <soap:body use='literal'/>
       </output>
       <fault name='PVNGAPIException'>
       <soap:fault name='PVNGAPIException' use='literal'/>
       </fault>
       </operation>
       <operation name='getAllValues'>
       <soap:operation soapAction=''/>
       <input>
       <soap:body use='literal'/>
       </input>
       <output>
       <soap:body use='literal'/>
       </output>
       <fault name='PVNGAPIException'>
       <soap:fault name='PVNGAPIException' use='literal'/>
       </fault>
       </operation>
       <operation name='getNames'>
       <soap:operation soapAction=''/>
       <input>
       <soap:body use='literal'/>
       </input>
       <output>
       <soap:body use='literal'/>
       </output>
       <fault name='PVNGAPIException'>
       <soap:fault name='PVNGAPIException' use='literal'/>
       </fault>
       </operation>
       </binding>
       <service name='PVNGDeviceService'>
       <port binding='tns:DeviceEndpointBinding' name='DeviceEndpointPort'>
       <soap:address location='REPLACE_WITH_ACTUAL_URL'/>
       </port>
       </service>
      </definitions>
      


      EJB endpoint remote interface that return collection Vector, ArratList, Hashtable etc..

      
      public interface DeviceEndpoint extends Remote {
       public ArrayList<String> getNames() throws RemoteException, PVNGAPIException;
       public Vector<String> getAllNames(String s) throws RemoteException, PVNGAPIException;
       public HashMap <String, ArrayList> getAllValues(String s) throws RemoteException, PVNGAPIException;
       public Hashtable <String, ArrayList> getAllHashValues(String s) throws RemoteException, PVNGAPIException;
      
      


      Please let me know if there is any workaround to this issue.

      Regards,
      Surafel

        • 1. Re: JBoss wstool generate incorrect WSDL file

          Have you tried updating to New JBoss WS stack which is out now - JbossWs 2.0.1 GA. Just download that and deploy it and then see what do u get.

          You are using Doc Literal wrapped style of service.
          I would say use wsconsume ans wsprovide which comes in new jbossws stack and is more Jax Ws complaint as compared o the one shipped in Jboss4.0.4

          If your consumer and provider are both using same stack then it should work seamlessly

          • 2. Re: JBoss wstool generate incorrect WSDL file
            itrahulsoni

            Hi
            There I want to know that how you have developed this webservice.
            I am new to webservice and try to deveop webservice for the JBoss using Ant.
            what tools I have need for that
            and how should I do that
            I know that I have to create war file using the ant task
            and then after I have to deploy that on the JBoss server
            how do i do that?????????


            Regards,
            Rahul.

            • 3. Re: JBoss wstool generate incorrect WSDL file

              I'm not using any tools, this one is created by hand (WSDL file) and used wsconsume to generate stubs and have my server side in .NET.

              What you can do is follow this guide and examples.
              Also Jbossws stack binary (seperate download is avaialble) have some examples in it in tools directory i think, that will give you clues as well
              http://labs.jboss.com/jbossws/docs/jaxws_userguide-2.0/index.html

              You should firt try to create an implementation and don't worry about ant target yet just create an exploded war file (like test.war directory) under deploy directoty and put yr pojo based class as SEI and declare it as servlet
              in web.xml file for that war.

              Use the JAX -ws user guide mentioned above
              and look at some steps described here for directory structure and deploy.
              http://wiki.jboss.org/wiki/Wiki.jsp?page=JBWS181HelloWorld
              dont create yr service/class file using this as this is not using annotations.
              Use the user guide examples for that

              I hope this helps.

              • 4. Re: JBoss wstool generate incorrect WSDL file
                mendaye

                Hello vashistvishal and others:

                Thanks for responding. My problem is the WSDL generated using JBoss 4.0.4 build in wstool for custom complex object and java collection class is wrong. I tried both RPC and doc style and it does't work when the return type is Java Collection object. I need to know if this is a known issue in 4.0.4 before I move to the latest JbossWs stack.

                Look below what I get for Hashtable, ArrayList, Vector and other custom objects...

                <schema targetNamespace='http://util.java/jaws' xmlns='http://www.w3.org/2001/XMLSchema' xmlns:ns1='h
                ttp://db.panduit.com/dbaccess/types' xmlns:soap11-enc='http://schemas.xmlsoap.org/soap/encoding/' xm
                lns:tns='http://util.java/jaws' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>


























                Do you think upgrading to the lasest Web Service help? Please help!

                Thanks,
                Surafel

                • 5. Re: JBoss wstool generate incorrect WSDL file
                  mendaye

                  Sorry the WSDL disappear in my message here it is
                  agin

                  <schema targetNamespace='http://util.java/jaws' xmlns='http://www.w3.org/2001/XMLSchema' xmlns:ns1='h
                  ttp://db.panduit.com/dbaccess/types' xmlns:soap11-enc='http://schemas.xmlsoap.org/soap/encoding/' xm
                  lns:tns='http://util.java/jaws' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
                  
                   <import namespace='http://db.panduit.com/dbaccess/types'/>
                   <complexType name='ArrayList'>
                   <sequence>
                   <element name='empty' type='boolean'/>
                   </sequence>
                   </complexType>
                   <complexType name='HashMap'>
                   <sequence>
                   <element name='empty' type='boolean'/>
                   </sequence>
                   </complexType>
                   <complexType name='Hashtable'>
                   <sequence>
                   <element name='empty' type='boolean'/>
                   </sequence>
                   </complexType>
                   <complexType name='Vector'>
                   <sequence>
                   <element name='empty' type='boolean'/>
                   <element name='size' type='int'/>
                   </sequence>
                   </complexType>
                   </schema>
                   </types>
                  

                  As shown above the WSDL for jave collection object was Wrong. Pls help to resolve this issue.


                  • 6. Re: JBoss wstool generate incorrect WSDL file

                    Yes, the wstools generated wsdl is not correct when using collections. If you need to stick to the jax-rpc stack, you should use arrays in spite of collections.
                    However I suggest upgrading to the jaxws stack (2.0.x) and use wsconsume/wsprovide tools; the jaxws version supports concrete collection types.

                    Alessio Soldano

                    • 7. Re: JBoss wstool generate incorrect WSDL file
                      mendaye

                      Thanks Alessio for responding to my question. Before I upgrade to the latest version of JBoss Web stack, Can some one answers the following questions.

                      1. How can I upgrade the latest JBoss web service stack?
                      2. Remember we are using JBoss 4.0.4 GA version, does jaxws stack (2.0.x) works with JBoss 4.04 version?
                      3. Does jaxws stack support EJB 2.1 as service end point?
                      3. Can you point me a tutorial on how to use wsconsume/wsprovide tools?

                      Regards,
                      Surafel

                      • 8. Re: JBoss wstool generate incorrect WSDL file
                        richard_opalka

                         

                        "mendaye" wrote:
                        Thanks Alessio for responding to my question. Before I upgrade to the latest version of JBoss Web stack, Can some one answers the following questions.

                        1. How can I upgrade the latest JBoss web service stack?
                        2. Remember we are using JBoss 4.0.4 GA version, does jaxws stack (2.0.x) works with JBoss 4.04 version?
                        3. Does jaxws stack support EJB 2.1 as service end point?
                        3. Can you point me a tutorial on how to use wsconsume/wsprovide tools?

                        Regards,
                        Surafel


                        Answers:
                        1. Just download JBoss 2.0.1, modify ant properties that are there and fire `ant deploy-jboss40` from commandline
                        2. JBossWS 2.01. is well tested on JBoss 4.0.5 GA but should work well with JBoss 4.0.4 GA too
                        3. Yes
                        4. http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4082256#4082256

                        • 9. Re: JBoss wstool generate incorrect WSDL file
                          mendaye

                          Thanks Richard for your answers. It is very helpful.
                          I wanted to make sure I am not running into any interoperablility isse using jaxws stack (2.0.x) with java collecion class. Can someone answer my question below.

                          1. If I use Java Collections object in my web service that will be JBoss jaxws stack (2.0.x) compliant, am I running to any interoperability issue for .NET consumer. I wanted to make sure these web services can be consumed by .NET client. I am exposing existing Stateless EJB as service end-point and it is not easy to replace Java Collections object.

                          2. I have requirement - only authorized users can consume these web services. Does JBossWS 2.0.x provide user authentication mechanism to do this? If so how?

                          3. If #2 (Web service consumer authentication) is possible, can you point me document that has examples on this.



                          Thanks,
                          Surafel

                          • 10. Re: JBoss wstool generate incorrect WSDL file

                             

                            "mendaye" wrote:
                            1. If I use Java Collections object in my web service that will be JBoss jaxws stack (2.0.x) compliant, am I running to any interoperability issue for .NET consumer. I wanted to make sure these web services can be consumed by .NET client. I am exposing existing Stateless EJB as service end-point and it is not easy to replace Java Collections object.

                            I don't think you'll have .NET compatibility issues with collections, however if Richard perfomed some tests on this please add your opinion. Anyway, generally speaking, jbossws compliance with standards should offer high compatibility with other stacks.


                            2. I have requirement - only authorized users can consume these web services. Does JBossWS 2.0.x provide user authentication mechanism to do this? If so how?

                            Yes, it does. See @WebContext and its property 'authMethod'.


                            3. If #2 (Web service consumer authentication) is possible, can you point me document that has examples on this.

                            I would take a look at the samples that ship with jbossws sources. For example, see org.jboss.test.ws.jaxws.samples.context.WebServiceContextEJBTestCase.

                            Alessio Soldano


                            • 11. Re: JBoss wstool generate incorrect WSDL file
                              mendaye

                              Thanks for Alessio Soldano responding quickly. It is very helpful! One last question...

                              Richard Opalka in this forum pointedout to me jbossws-2.0.x work with JBoss 4.0.4 but that is not mentioned in release note of jbossws-2.0.1.GA. Look below..
                              http://www.jboss.com/index.html?module=bb&op=viewtopic&t=116889
                              Based on this link, jbossws-2.0.1.GA supports only jboss-5.0.x, jboss-4.2.x, jboss-4.0.5.

                              As I said before, we have JBoss-4.0.4, before I start coding I wanted to make sure jbossws-2.0.1.GA runs on JBoss-4.0.4. Please if you know for sure 4.0.4 supports jbossws-2.0.1.GA, respond back to me so that I can start my coding work

                              Thanks,
                              Surafel

                              • 12. Re: JBoss wstool generate incorrect WSDL file

                                For option 2 use this ... if it is just a basic authentication which i have been using on client side.
                                Their are examples in JbossWS stack examples

                                
                                MattHelloWorld3Service service = new MattHelloWorld3Service();
                                
                                MattHelloWorld3PortType port = service.getPort(MattHelloWorld3PortType.class) ;
                                
                                // Get the port and use binding provider for authentication
                                
                                BindingProvider bp = (BindingProvider) port;
                                
                                bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "test");
                                
                                bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "test");
                                
                                
                                HelloWorld memreq = new HelloWorld();
                                
                                memreq.setId("Hellow Mathew");
                                
                                


                                I hope this helps