11 Replies Latest reply on Jul 28, 2008 2:08 PM by dakk

    Looking to pass complex types in web service...

    dakk

      OK, so I am a newbie... I've got the example from chapter 12 running -- the Hello example -- that passes a string. I'd like to modify the example to pass in say 2 strings, and return a complex type that is made up of ints and strings. I am using JBoss 4.2.0, and JWSDP 2.

      I think I've gotten a long way (I can at least invoke the service) but I am getting serialization errors (null ptr error) from com.sun.xml.rpc.encoding.DynamicInternalTypeMappingRegistry.getSerializer() - where the cause is emanating from com.sun.xml.rpc.encoding.literal.ValueTypeLiteralSerializer.doSetTargetClass().

      What I am wondering is if I can really use the same approach that the Hello example used (i.e., ServiceFactory.createService, service.getPort, and then invoke my service method), or if I really need to use another API to pass complex types.

      Any help would be appreciated!

      Norm

        • 1. Re: Looking to pass complex types in web service...
          peterj

          As long as the complex type implements Serializable, then it should work.

          Please post the full exception stack trace you are getting - it is hard to pinpoint the error with it. Also, post the source for the complex class (you can leave out the methods).

          • 2. Re: Looking to pass complex types in web service...
            peterj

            I meant "it is hard to pinpoint the error without it"

            • 3. Re: Looking to pass complex types in web service...
              dakk

              Thanks for your help! Norm

              The class is:
              ========
              import java.util.Date;

              /**
              *
              * @author dakk
              */
              public class DataRecord implements java.io.Serializable {

              public String fileName;
              public byte[] photo; //as an array of base64-encoded bytes
              public Float salary;
              public Float d2;
              public Float d3;
              public Float d4;
              public Date date;
              public Integer empID;
              public Float d5;

              public DataRecord() {}

              public String toString() {
              return "Data Record Filename="+this.fileName;
              }
              }


              Here is the run:
              ===================================
              init:
              deps-jar:
              compile-single:
              run-single:
              Contacting webservice at http://localhost:8080/myservlet/MyServletInterface?wsdl
              Exception in thread "main" deserialization error: unexpected XML reader state. expected: END but found: START: date
              at com.sun.xml.rpc.encoding.literal.LiteralResponseSerializer.deserialize(LiteralResponseSerializer.java:331)
              at com.sun.xml.rpc.client.dii.CallInvokerImpl._readFirstBodyElement(CallInvokerImpl.java:350)
              at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:228)
              at com.sun.xml.rpc.client.dii.CallInvokerImpl.doInvoke(CallInvokerImpl.java:103)
              at com.sun.xml.rpc.client.dii.BasicCall.invoke(BasicCall.java:486)
              at com.sun.xml.rpc.client.dii.CallInvocationHandler.doCall(CallInvocationHandler.java:121)
              at com.sun.xml.rpc.client.dii.CallInvocationHandler.invoke(CallInvocationHandler.java:85)
              at $Proxy0.getDataRecord(Unknown Source)
              at MyClient.main(MyClient.java:48)

              CAUSE:

              unexpected XML reader state. expected: END but found: START: date
              at com.sun.xml.rpc.streaming.XMLReaderUtil.verifyReaderState(XMLReaderUtil.java:51)
              at com.sun.xml.rpc.encoding.literal.LiteralResponseSerializer.internalDeserialize(LiteralResponseSerializer.java:373)
              at com.sun.xml.rpc.encoding.literal.LiteralResponseSerializer.deserialize(LiteralResponseSerializer.java:327)
              at com.sun.xml.rpc.client.dii.CallInvokerImpl._readFirstBodyElement(CallInvokerImpl.java:350)
              at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:228)
              at com.sun.xml.rpc.client.dii.CallInvokerImpl.doInvoke(CallInvokerImpl.java:103)
              at com.sun.xml.rpc.client.dii.BasicCall.invoke(BasicCall.java:486)
              at com.sun.xml.rpc.client.dii.CallInvocationHandler.doCall(CallInvocationHandler.java:121)
              at com.sun.xml.rpc.client.dii.CallInvocationHandler.invoke(CallInvocationHandler.java:85)
              at $Proxy0.getDataRecord(Unknown Source)
              at MyClient.main(MyClient.java:48)
              Java Result: 1
              BUILD SUCCESSFUL (total time: 17 seconds)

              • 4. Re: Looking to pass complex types in web service...
                dakk

                Any chance this could be as simple as adjusting the wscompile params? I am currently using:














                • 5. Re: Looking to pass complex types in web service...
                  peterj

                  Enclose your XML text in UBBCode "code" tags - you can do this by selecting the XML text and clicking the Code button above the editor window. Also, click the Preview button to ensure that the formatting is correct and the XML text shows up before posting.

                  • 6. Re: Looking to pass complex types in web service...
                    dakk

                     

                    "PeterJ" wrote:
                    Enclose your XML text in UBBCode "code" tags - you can do this by selecting the XML text and clicking the Code button above the editor window. Also, click the Preview button to ensure that the formatting is correct and the XML text shows up before posting.


                    ...Are you referring to the XML msgs related to method invocation? If so, I am not generating the XML... this is all being handled by the stubs that I believe that wscompile generated.

                    Please clarify if I misunderstood, or tell me a little more about how I would do this. (Is there a switch in wscompile that would help?)

                    Thanks again!!

                    • 7. Re: Looking to pass complex types in web service...
                      dakk

                      Wow... ok I am apparently SLOW. I thought you were providing a solution! I didn't see my previous post (which obviously has hidden XML)! Here is the XML for running wscompile:

                      Btw, is there a way to see the XML that is being sent? Not that I could remedy the problem, but the stub code that wscompile is generating is compiled. I prefer to be able to instrument this so I can see what xml it is passing around.

                      Thanks!!

                      Norm

                       <target name="run-wscompile" depends="prepare">
                       <exec executable="C:/Sun/jwsdp-2.0/jaxrpc/bin/wscompile.bat">
                       <arg value="-classpath" />
                       <arg value="${build.dir}/classes" />
                       <arg value="-gen:both" />
                       <arg value="-f:rpcliteral" />
                       <arg value="-mapping" />
                       <arg value="${src.dir}/myService/meta/mapping.xml" />
                       <arg value="-d" />
                       <arg value="${src.dir}/myService/server/wsdl" />
                       <arg value="${src.dir}/myService/server/config.xml" />
                       </exec>
                       </target>
                      


                      • 8. Re: Looking to pass complex types in web service...
                        peterj

                        So see the SOAP messages on the server, edit the server/xxx/conf/jboss-log4j.xml file, uncommenting the org.jboss.ws.core.MessageTrace category. To see them on the client provide a log4j config file that enables the same category.

                        Also, have you tried removing the "byte[] photo" field? I am guessing that it might be the cause. If it works without that, we will at least know where to focus our effort.

                        I was about to say "Please post your mapping.xml file.", but decided to check the options before I did so to make sure that it was not a file that was being generated. But there is no such thing as wscompile in JBoss Web Services. There is a wsconsume, wsprovide, and wsrunclient (and a wstools, but it is for the old-style web services). And based in the command line, it appears that wscompile is part of Sun's web service's implementation. You really need to sue the JBoss Web Service tools.

                        • 9. Re: Looking to pass complex types in web service...
                          dakk

                          Peter,

                          I guess I'd prefer not to waste your time (or anyone else that might help me) to debug a Sun tool if there is a better, more reliable way to go... I was led down this path as a newbie by following any example I got from the JBoss site (some book on JBoss).

                          If there is another example, or simple docs that'll walk me thru sending a complex type, by all means I am eager to go that route instead!

                          Thanks for your fast response to this, I'd really like to get this working asap!

                          Norm

                          • 10. Re: Looking to pass complex types in web service...
                            peterj

                            I don't know of an example that uses a complex type, but there is documentation on JBoss Web Services, and its tools, at http://jbws.dyndns.org/mediawiki/index.php?title=JAX-WS_User_Guide.

                            I also have another resource, but it is not free, nor does it cover complex types, but it does walk you through a complete example. I can supply the URL if you like.

                            • 11. Re: Looking to pass complex types in web service...
                              dakk

                              UPDATE:
                              =====

                              I went back and started by reducing the data struct I was passing to just one attribute, then two, then ... etc., until I found the problems.

                              1) It turns out that one problem I had was that two attrs started with capital letters (my bad)... neither javac or wscompile caught this, but it did cause parsing errors.

                              2) It also does not like the java.util.Date type. I suppose I can convert this to a string and then back to a date. (I get the same parsing error I got before - something like 'saw START but expected END'...

                              3) It was having trouble parsing the byte array (that will store up to a 1.5MB image), that at this point only contained a string converted to bytes. I changed that attr to a String and then Base64 encoded the bytes and it works fine.

                              --> If there is a more efficent way to pass a 1.5MB file back in a response, please let me know.

                              Thanks!

                              Norm.