This discussion is archived
9 Replies Latest reply: Jan 31, 2013 10:01 PM by User252311 RSS

Weblogic 10.3 - Arrays and JAX-RPC Web Services

674471 Newbie
Currently Being Moderated
We are currently looking at migrating from WL 8.1 to WL 10.3, and have an issue with some of our web services (JAX-RPC) with regards to returning String arrays.

We have a web service method that returns a response object. This response object has many properties that includes a property that is a String array. So the code looks something like this (this is a simplified version):

<em>public class OurService
{
@RemoteMethod
@WebMethod
@WebResult(name = "result")
public ResponseObject lookup(String someParam)
{
// build the object and its properties here...

return responseObject;
}
}</em>

This is what the response object looks like:

<em>public class ResponseObject
{
private String[] someProperty;

public String[] getSomeProperty()
{
return this.</em><em>someProperty</em><em>;
}

public void setSomeProperty(String[] </em><em>someProperty</em><em>)
{
this.</em><em>someProperty</em><em>= </em><em>someProperty</em><em>;
}
}</em>

So the issue is this. In WL 8.1, the web service generator would recognise the fact that the response object had a property that was a String array and would declare as such in the WSDL file, for example:

<em><strong> &lt;xsd:element xmlns:tp="java:language_builtins.lang" type="<font color="#ff0000">tp:ArrayOfString</font>" name="someProperty" minOccurs="1" nillable="true" maxOccurs="1"&gt;
&lt;/xsd:element&gt;
</strong></em>
As a result, when the service is called, the property is returned in the SOAP response like this:

<strong>.
.
.
</strong>
<div class="e">
<div class="c" style="margin-left: 1em; text-indent: -2em">
<em><strong> <span class="m">&lt;</span><span class="t">someProperty</span><span class="t"> soapenc:arrayType</span><span class="m">="</span></strong><strong>xsd:string[2]<span class="m">"</span><span class="m">&gt;</span></strong></em>
</div>
<div>
<div class="e">
<div>
<em><strong><span class="b"> </span><span class="m">&lt;</span><span class="t">string</span><span class="t">
xsi:type</span><span class="m">="</span></strong><strong>xsd:string<span class="m">"</span><span class="m">&gt;</span><span class="tx">string1</span><span class="m">&lt;/</span><span class="t">string</span><span class="b">&gt;
&lt;string xsi:type="xsd:string"&gt;string2&lt;/string&gt;
</span><span class="m">&lt;/</span><span class="t">someProperty</span><span class="m">&gt;</span></strong></em>
</div>
</div>
</div>
</div>
<strong>.
.
.
</strong>
But, in WL 10.3, the WSDL entry is:

<em><strong> &lt;xs:element maxOccurs="unbounded" minOccurs="0" name="InstepCodes" nillable="true" type="xs:string"&gt;
</strong></em>
As a result the property is returned in the SOAP response like this:

<strong> .
.
.
</strong><strong><span class="m"> &lt;</span><span class="t">java:InstepCodes</span><span class="ns">
xmlns:java</span><span class="m">="</span></strong><strong class="ns">java:com.myservice</strong><strong><span class="m">"</span><span class="m">&gt;</span><span class="tx">string1</span><span class="m">&lt;/</span><span class="t">java:InstepCodes</span><span class="m">&gt;</span>
</strong><strong><span class="m"> &lt;</span><span class="t">java:InstepCodes</span><span class="ns">
xmlns:java</span><span class="m">="</span></strong><strong class="ns">java:com.myservice</strong><strong><span class="m">"</span><span class="m">&gt;</span><span class="tx">string2</span><span class="m">&lt;/</span><span class="t">java:InstepCodes</span><span class="m">&gt;</span>
.
.
.

</strong>The difference here is that WL 10.3 does not return the array of strings as a complex array type, just as a set of repeated elements.

We need to return the array as we do for WL 8 in WL 10.3, because we have external clients that are parsing the response and looking for the XML in this format. We are not currently in a position to ask them to change.

Is this a limitation of the JAX-RPC spec, or WL's implementation of it?

If the service was to return a String array directly from a service method, then it is declared in the WSDL file.

However, if a service returns an object that within itself has a property that is an array, it does not recognise it like it did with WL 8.1.
<strong>
</strong>
<div class="e">

</div>
  • 1. Re: Weblogic 10.3 - Arrays and JAX-RPC Web Services
    668491 Newbie
    Currently Being Moderated
    Just a thought:

    would a feasible workaround be to take the WSDL that 8.1 generated, start with that and run WSDLC in 10.3 to generate the Java Interfaces corresponding to the WSDL that you want. Then port the service to fit the generated interface ?
    This is if the existing clients must recieve the sameXML messages, and if there is no way to affect JWSC in 10.3 to generate WSDL to match the 8.1 WSDL given the existing Java Service implementation..
  • 2. Re: Weblogic 10.3 - Arrays and JAX-RPC Web Services
    674471 Newbie
    Currently Being Moderated
    Thanks for the reply.

    I have tried the WSDLC task on both the 8.1 and 10.3 WSDL's and both of them generate the same, correct code, i.e. a web service method that returns a String array.

    The WL 10.3 WSDL generates the right code because it has the maxOccurs="unbounded" and minOccurs="0" attribute set for the element.

    So the mystery is still why it does not generate the same SOAP response as 8.1.

    Any more ideas?
  • 3. Re: Weblogic 10.3 - Arrays and JAX-RPC Web Services
    668491 Newbie
    Currently Being Moderated
    AFAIK the WebService version story in WLS from 8.1 is like this:
    In 8.1 there were 2 separate BEA WebService stacks:
    1. the 'WebLogic Server' stack
    2. the 'WebLogic Workshop' stack

    (I note that I never did ask which 8.1 version you are using).

    By release 9 (when I joined the WebService stack development team), the 'WebLogic' stack was completely re-written and has nothing in common with the 8.1 stack. Also, BEA wisely decided that it made sense to have only 1 WebService stack, and that stack would be the WebLogic Server stack.

    Release 10 and 10.3 are based on the release 9 stack.
    It's not quite the answer you're looking for but the 8.1 stack and the 9-10 stack are completely different and may exhibit very different behaviors (I think the 8.1 stack may not be JAX-RPC 1.1 compliant, whereas the 9-10 stack is).

    WRT to the mapping of Java Arrays to XML, I notice that the JAX-RPC 1.1 spec, section 5.3.4 lists 4 different ways in which they allow a Java Arrays to be mapped to XML/WSDL types (including the JavaBean approach).

    I'm a little puzzled. You say that 10.3 generates ONLY an unbounded element to represent the String[], with no complexType wrapper ? If that's true, it seems to violate the JAX-RPC spec (above mentioned section 5.3.4)..
  • 4. Re: Weblogic 10.3 - Arrays and JAX-RPC Web Services
    674471 Newbie
    Currently Being Moderated
    Thank you for the reply.

    We are using WL Server 8.1 (not Workshop), and moving to WL Server 10g R3.

    We are using the JWSC task to generate the service, which is:

    bq. weblogic.wsee.tools.anttasks.JwscTask+
    Here is an extract from the Ant build file the calls the task.

    &lt;jwsc
    srcdir="src/com/ourservice"
    sourcepath="src"
    destdir="${ear.dir}"
    verbose="false"
    debug="true"
    keepGenerated="true"
    classpathref="ws.class.path"&gt;
    +&lt;module name="${service.name}" explode="true"&gt;+
    +&lt;jws file="OurService.java" type="JAXRPC"/&gt;+
    +&lt;/module&gt;+
    +&lt;/jwsc&gt;+

    As stated in my first post, the service method returns an reponse object and its this that contains the array property. The service method itself does not return an array type. This seems to be the root of the problem, i.e. the declaration of array types is not being propagated down through the object graph the service method returns. Below is the code for the service and the response object.

    @FileGeneration(remoteClass = Constants.Bool.TRUE, remoteClassName = "OurService", localHome = Constants.Bool.TRUE, localHomeName = "OurServiceLocalHome", remoteHome = Constants.Bool.TRUE, remoteHomeName = "++OurService++Home", localClass = Constants.Bool.TRUE, localClassName = "++OurService++Local")+
    @JndiName(remote = "com.ourservice.++OurService++", local = "com.ourservice.++OurService++Local")+
    @Session(ejbName = "++OurService++", type = Session.SessionType.STATELESS, transactionType = Session.SessionTransactionType.CONTAINER, maxBeansInFreePool = "100", initialBeansInFreePool = "20", enableCallByReference = Constants.Bool.TRUE, homeIsClusterable = Constants.Bool.TRUE, homeLoadAlgorithm = Constants.HomeLoadAlgorithm.ROUND_ROBIN, isClusterable = Constants.Bool.TRUE, beanLoadAlgorithm = "RoundRobin", defaultTransaction = Constants.TransactionAttribute.SUPPORTS)+
    +@RoleMappings( { @RoleMapping(roleName = "Admin", externallyDefined = Constants.Bool.TRUE),+
    +@RoleMapping(roleName = "Monitor", externallyDefined = Constants.Bool.TRUE),+
    +@RoleMapping(roleName = "JMS", externallyDefined = Constants.Bool.TRUE) })+
    @WebService(name = "OurServicePort", serviceName = "OurService", targetNamespace = "http://www.ourservice.com/SOA/OurService+_service")+
    +@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL)+
    @WLHttpTransport(contextPath = "OurService", serviceUri = "OurService", portName = "
    *OurService+Port")+
    public class OurService
    +{+
    @RemoteMethod
    @WebMethod
    @WebResult(name = "result")


    {color:#ff0000}public ResponseObject lookup(String someParam){color}



    {
    // build the response object...



    return {color:#ff0000}responseObject{color};



    }
    +}+

    This is what the response object looks like:

    public class ResponseObject
    +{+
    private String[] someProperty;

    +public {color:#ff0000}String[] getSomeProperty(){color}+
    +{+
    return this.someProperty;
    +}+

    public void setSomeProperty(String[] someProperty)
    +{+
    this.someProperty = someProperty;
    +}+
    +}+

    From all of this I cant tell how we get the WSDL file to delcare it as an array type, as shown in the JAX-RPC 1.1 spec you mentioned, based on the code we have and the JWSC build task we are using.

    (I appologise for the formatting of this message. It seems to want to insert + everywhere in the code examples, despite me removing them!)

    Edited by: user8013492 on 11-Dec-2008 02:09

    Edited by: user8013492 on 11-Dec-2008 02:11
  • 5. Re: Weblogic 10.3 - Arrays and JAX-RPC Web Services
    668491 Newbie
    Currently Being Moderated
    Out of curiousity, I spent a little time this evening writing a Start from Java service that has a method that passes a JavaBean containing only a single String[] property.

    jwsc compiled this fine and created a WSDL with a plain complex type with a single unbounded xs:string element representing the JavaBean (that is not the soapenc array version that is also allowed by the JAX-RPC spec).

    <xs:complexType name="DocLitWrapBasicStruct">
    <xs:sequence>
    <xs:element maxOccurs="unbounded" minOccurs="0" name="StringArray" nillable="true" type="xs:string"/>
    </xs:sequence>
    </xs:complexType>

    This seems fine to me.

    Then I ran clientgen on the resulting wsdl, with the JaxRPCWrappedArrayStyle="true" option set, this causes clientgen to create the JavaBean wrapper for the unbounded xs:string element of the complexType "DocLitWrapBasicStruct":

    <clientgen
    wsdl="jar:file:${output.dir}/SimpleImpl.war!/WEB-INF/SimpleImplService.wsdl"
    destDir="${clientclasses.dir}"
    JaxRPCWrappedArrayStyle="true"
    packageName="style.doclitwrappedstringarraybean.client">
    <classpath refid="style_doclitwrappedstringarraybean.client.classpath"/>
    </clientgen>

    so the test client uses the JavaBean as an argument in the generated proxy method (not the bare String[]):

    DocLitWrapBasicStruct in = new DocLitWrapBasicStruct();
    in.setStringArray(sArray);
    DocLitWrapBasicStruct result = port.echoDocLitWrapBasicStruct(in);

    The message over the wire looks good (the style is document literal wrapped so there's the operation wrapper element 'echoDocLitWrapBasicStruct' outer element containing the element representing the JavaBean:

    <m:echoDocLitWrapBasicStruct xmlns:m="http://style/docLitWrappedStringArrayBean">
    <m:bs xmlns:java="java:style.doclitwrappedstringarraybean">
    <java:StringArray>0</java:StringArray>
    <java:StringArray>1</java:StringArray>
    <java:StringArray>2</java:StringArray>
    </m:bs>
    </m:echoDocLitWrapBasicStruct>



    This is the JavaBean, the original and the one that clientgen regenerates from the WSDL are the same:

    /**
    * Generated from schema type t=DocLitWrapBasicStruct@java:style.doclitwrappedstringarraybean
    */
    package style.doclitwrappedstringarraybean;

    public class DocLitWrapBasicStruct implements java.io.Serializable {

    private java.lang.String[] stringArray;

    public java.lang.String[] getStringArray() {
    return this.stringArray;
    }

    public void setStringArray(java.lang.String[] stringArray) {
    this.stringArray = stringArray;
    }

    }

    So, I"m able to generate a proper WSDL from the JWS with a JavaBean, and have
    clientgen regenerate the JavaBean from the WSDL so that the client can be written to use the JavaBean as an arg.


    This all seems to be working right to me (here).
    If you'd like a jar of my source and compiled generated code,
    send me a request at:

    thorick.chow@oracle.com

    And be sure to remind me that you're after the jars in the e-mail subject...
  • 6. Re: Weblogic 10.3 - Arrays and JAX-RPC Web Services
    668491 Newbie
    Currently Being Moderated
    One thing, wrt getting 'the WSDL file to declare it as an array type' as in:

    "From all of this I cant tell how we get the WSDL file to delcare it as an array type, as shown in the JAX-RPC 1.1 spec you mentioned, based on the code we have and the JWSC build task we are using."

    Do you mean that you want JWSC to produce an element that's one of the 'soapenc' Array types ?
  • 7. Re: Weblogic 10.3 - Arrays and JAX-RPC Web Services
    674471 Newbie
    Currently Being Moderated
    May thanks for looking into this, much appreciated.

    To be honest the statement "Do you mean that you want JWSC to produce an element that's one of the 'soapenc' Array types ?" was more out of hope than anything else (i.e. I dont suppose there is a magic switch anywhere!).

    But as your test harness seems to give the expected result then its a matter of going back and trying it at our end to see what happens. I will post my findings back here.
  • 8. Re: Weblogic 10.3 - Arrays and JAX-RPC Web Services
    668491 Newbie
    Currently Being Moderated
    Yeah, unfortunately, there's no switch for document-literal style JWSs to produce 'soapenc' style arrays.

    I have run 10.3 JWSC on rpc-encoded style services in which 'soapenc' array types ARE used (in this case for 2 dimensional String Arrays String[][], e.g.:

    <s1:complexType name="ArrayOfArrayOfJavaLangstring">
    <s1:complexContent>
    <s1:restriction base="soapenc:Array" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
    <s1:sequence>
    <s1:element maxOccurs="unbounded" name="JavaLangstring" nillable="true" type="xs:string"/>
    </s1:sequence>
    <s1:attribute ref="soapenc:arrayType" wsdl:arrayType="xs:string[,]" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>
    </s1:restriction>
    </s1:complexContent>
    </s1:complexType>

    Haven't tried it for 1 dimensional String[] in RPC-Encoded though.
    But the fact remains, that yes, there is no switch to control the generation of these, though the runtime should accept and (un)marshal all the various array types.

    If your clients must have soapenc Arrays on the wire, I still think using WSDLC on a WSDL that defines soapenc Arrays is the only possible avenue.. Let us know how it goes !
  • 9. Re: Weblogic 10.3 - Arrays and JAX-RPC Web Services
    User252311 Newbie
    Currently Being Moderated
    Hello

    We are migrating our web services to weblogic 12 C and facing the same problem. Could you please suggest how did you resolve it?

    We also need to return the array as we do for WL 8 in WL 12 C.

    I will appreciate your response as soon as possible.

    Thanks
    Sandeep Wadhwa
    Technical Architect

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points