views:

1048

answers:

3

So, I'm getting some compile errors on netbeans 6.5 generated web service code for a java ME client to a c# (vs2005) web service. I've trimmed my example significantly, and it still shows the problem, and not being able to return a collection of things is pretty much a deal-breaker.

c# web service (SimpleWebService.asmx)

<%@ WebService Language="C#" Class="SimpleWebService" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace = "http://sphereinabox.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class SimpleWebService  : System.Web.Services.WebService {

    [WebMethod]
    public CustomType[] GetSomething() {
        return new CustomType[] {new CustomType("hi"), new CustomType("bye")};
    }
    public class CustomType {
     public string Name;
     public CustomType(string _name) {
      Name = _name;
     }
     public CustomType() {
     }
    }
}

WSDL (automatically generated by vs2005):

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://sphereinabox.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://sphereinabox.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"&gt;
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://sphereinabox.com/"&gt;
      <s:element name="GetSomething">
        <s:complexType />
      </s:element>
      <s:element name="GetSomethingResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="GetSomethingResult" type="tns:ArrayOfCustomType" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:complexType name="ArrayOfCustomType">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="CustomType" nillable="true" type="tns:CustomType" />
        </s:sequence>
      </s:complexType>
      <s:complexType name="CustomType">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
        </s:sequence>
      </s:complexType>
    </s:schema>
  </wsdl:types>
  <wsdl:message name="GetSomethingSoapIn">
    <wsdl:part name="parameters" element="tns:GetSomething" />
  </wsdl:message>
  <wsdl:message name="GetSomethingSoapOut">
    <wsdl:part name="parameters" element="tns:GetSomethingResponse" />
  </wsdl:message>
  <wsdl:portType name="SimpleWebServiceSoap">
    <wsdl:operation name="GetSomething">
      <wsdl:input message="tns:GetSomethingSoapIn" />
      <wsdl:output message="tns:GetSomethingSoapOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="SimpleWebServiceSoap" type="tns:SimpleWebServiceSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="GetSomething">
      <soap:operation soapAction="http://sphereinabox.com/GetSomething" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="SimpleWebServiceSoap12" type="tns:SimpleWebServiceSoap">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="GetSomething">
      <soap12:operation soapAction="http://sphereinabox.com/GetSomething" style="document" />
      <wsdl:input>
        <soap12:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="SimpleWebService">
    <wsdl:port name="SimpleWebServiceSoap" binding="tns:SimpleWebServiceSoap">
      <soap:address location="http://localhost/SimpleWebService/SimpleWebService.asmx" />
    </wsdl:port>
    <wsdl:port name="SimpleWebServiceSoap12" binding="tns:SimpleWebServiceSoap12">
      <soap12:address location="http://localhost/SimpleWebService/SimpleWebService.asmx" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Generated (netbeans) code that fails to compile, this was created going through the "Add -> New JavaME to Web Services Client" wizard. (SimpleWebService_Stub.java)

    public ArrayOfCustomType GetSomething() throws java.rmi.RemoteException {
        Object inputObject[] = new Object[] {
        };

        Operation op = Operation.newInstance( _qname_operation_GetSomething, _type_GetSomething, _type_GetSomethingResponse );
        _prepOperation( op );
        op.setProperty( Operation.SOAPACTION_URI_PROPERTY, "http://sphereinabox.com/GetSomething" );
        Object resultObj;
        try {
            resultObj = op.invoke( inputObject );
        } catch( JAXRPCException e ) {
            Throwable cause = e.getLinkedCause();
            if( cause instanceof java.rmi.RemoteException ) {
                throw (java.rmi.RemoteException) cause;
            }
            throw e;
        }

//////// Error on next line, symbol ArrayOfCustomType_fromObject not defined
        return ArrayOfCustomType_fromObject((Object[])((Object[]) resultObj)[0]);
    }

it turns out with this contrived example (the "CustomType" in my production problem has more than one field) I also get errors from this fun code in the same generated (SimpleWebService_Stub.java) generated code. The errors are that string isn't defined (it's String in java, and besides I think this should be talking about CustomType anyway).

private static string string_fromObject( Object obj[] ) {
    if(obj == null) return null;
    string result = new string();
    return result;
}
A: 

Clearly you shouldn't be using fancy built-in things like netbeans's stub generator. Noes, you should be using the Sun (or Sprint branded...) stub generator which you can get to by:

  1. Right-Clicking your project
  2. select Properties
  3. Select Platform on the left side of new dialog
  4. Click on Manage Emulators on the rigt side
  5. Select the emulator of your choice (Sun Java(TM) Wirless Tookit 2.5 for CLDC) on the left of this new dialog
  6. Click on the Tools & Extensions tab.
  7. Click the Open Utilities button.
  8. Select the Stub Generator Utility in this new dialog
  9. Cry about the large number of steps and dialogs involved.
  10. Click Launch
  11. Specify your WSDL Url http://localhost/SimpleWebService/SimpleWebService.asmx?WSDL
  12. Specify your ouput path ** C:\code\SimpleMobile\src\ **
  13. Specify your output package simplewebservice or whatever you
  14. Press the OK button.
  15. Ignore the errors about being unable to compile if you're going to compile with netbeans. error : com.sun.tools.javac.Main is not availble in the classpath.. error: comilation failed, errors should have been reported
  16. Repeat all of the above any time the web service changes, and the stubs need to be regenerated.
  17. Write a batch file to do this to save your sanity.

ugh. Well anyway, the above I found in Jonathan Knudsen's book "Kicking Butt with MIDP and MSA: Creating Great Mobile Applications"

sphereinabox
A: 

The previous answer is great, I had classcastexception when I used the netbeans generated stub class, java me platform SDK 3 generated class works like a charm.

Java ME platform SDK 3 and netbeans 6.8 does not show the open utilities button (can't click on it), but you can open Java ME platform SDK 3 to generate the stub class

create a new project, right click on project name: add - other choose other, mobile web service client, specify WSDL URL and woila, you have the working generated classes.

Psysoul
A: 

in web service add attribute [Serializable] for class CustomType. the you will get ArrayOfCustomType_fromObject() in stub class.

Rakhi