You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Xavier Luiz <xl...@thinkpassenger.com> on 2008/01/09 17:29:56 UTC

cxf wsdl2java and java2wsdl issue

Hi,

I'm not sure if this has been resolved or what the answer is on this but
the 2.0.4 incubator snapshot WSDL2Java and Java2WSDL tools are not
creating the return types that our application needs.  Here's the
underlying issue...

Is it possible to return a custom object array instead of a
java.util.List?
 

Here's the example class I have that returns a collection of objects.
With everything I've read and tried it looks like the CXF Java2WSDL and
WSDL2Java classes doesn't build a wsdl with the correct element and
sequence tree in order for the WSDL2Java to build the correct service
stub.  Any help is greatly appreciated.
 

Here's my class examples...
 

Interface class:
package com.cifrato.external.ws;
 

import com.cifrato.data.wrapper.StockQuote;
 

import javax.jws.WebService;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebMethod;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;

 

@SOAPBinding(style=Style.DOCUMENT,use=Use.LITERAL) 
@WebService(name="StockQuoteServicePortType") 
public interface StockQuoteService {
            @RequestWrapper(className="java.lang.String")
 
@ResponseWrapper(className="com.cifrato.data.wrapper.StockQuote")
            @WebResult(name="StockQuote")
            @WebMethod(operationName="getQuotes",exclude=false)
            public StockQuote[] getQuotes(@WebParam(name = "symbols")
String[] symbols);

}

 

 

Implementation class:
package com.cifrato.external.ws;

 

import com.cifrato.data.wrapper.StockQuote;

public class StockQuoteServiceImpl implements StockQuoteService {

 

            public StockQuote[] getQuotes(String[] symbols) {
                        StockQuote[] quotes = null;
                        if (symbols != null && symbols.length != 0) {
                                    quotes = new
StockQuote[symbols.length];
                                    for (int i = 0; i < symbols.length;
i++) {
 
quotes[i].setSymbol(symbols[i]);
                                                quotes[i].setPrice(i + 1
* 5);
                                    }
                        } else {
                                    quotes = new StockQuote[2];
                                    quotes[0].setSymbol("IBM");
                                    quotes[0].setPrice(50);
                                    quotes[1].setSymbol("MSFT");
                                    quotes[1].setPrice(100);
                        }

                        return quotes;
            }

}

 

 

Custom object class to return as a collection:
package com.cifrato.data.wrapper;

 

public class StockQuote {
 

	private String symbol;
	private int price;
	public String getSymbol() {
		return symbol;

	}

            public void setSymbol(String symbol) {
                        this.symbol = symbol;

            }

            public int getPrice() {
                        return price;

            }

            public void setPrice(int price) {
                        this.price = price;

            }

            

}

 

Build.xml:
<?xml version="1.0"?>
<project name="cxf-test" basedir=".">

            <property environment="system" />
            <property name="host.name" value="localhost" />
            <property name="java.home" value="${system.JAVA_HOME}"/>
            <property name="jetty.home" value="${system.JETTY_HOME}" />
            <property name="hamachi.home"
value="${system.JETTY_HOME}/hamachi" />
 
            <echo message="${os.name}"/>

            

    <path id="cxf.classpath">
        <fileset dir="lib">
            <include name="*.jar"/>
        </fileset>

    </path>

            

            <!--
================================================================== -->

            <!-- GENERATE WSDL FROM WEB SERVICE CLASSES FROM SERVER
PACKAGE         -->

            <!--
================================================================== -->

            <target name="test.wsdl" depends="server"
description="GENERATE WSDL">
                        <delete file="test.wsdl" quiet="true"/>
                        <delete dir="build/wsdl" quiet="true"/>
                        <mkdir dir="build/wsdl"/>
                        <java
classname="org.apache.cxf.tools.java2wsdl.JavaToWSDL" fork="true">
                                    <classpath refid="cxf.classpath"/>
                                    <arg value="-cp"/>
                                    <arg
value="lib/cifrato_server.jar"/>
                                    <arg value="-o"/>
                                    <arg value="test.wsdl"/>
                                    <arg value="-d"/>
                                    <arg value="build/wsdl"/>
                                    <arg value="-quiet"/>
                                    <arg
value="com.cifrato.external.ws.StockQuoteService"/>
                        </java>
            </target>

            

            <!--
================================================================== -->

            <!-- GENERATE JAVA FROM WSDL  wsdl2java -d build/classes
-compile ./wsdl/hello_world.wsdl -->

            <!--
================================================================== -->
            <target name="test.stub">
                        <copy file="build/wsdl/test.wsdl"
todir="${basedir}" overwrite="true" />
                        <delete
dir="src/java/client/com/cifrato/client/external/cxf/ws" quiet="true"/>
                        <mkdir
dir="src/java/client/com/cifrato/client/external/cxf/ws"/>
                        <java
classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true">
                                    <classpath refid="cxf.classpath"/> 
                                    <arg value="-client" />
                                    <arg value="-p" />
                                    <arg
value="com.cifrato.client.external.cxf.ws"/>
                                    <arg value="-d" />
                                    <arg value="src/java/client" />
                                    <arg value="${basedir}/test.wsdl" />
                        </java>
            </target>

</project>

Re: cxf wsdl2java and java2wsdl issue

Posted by Daniel Kulp <dk...@apache.org>.
On Wednesday 09 January 2008, Xavier Luiz wrote:
> I'm not sure if this has been resolved or what the answer is on this
> but the 2.0.4 incubator snapshot WSDL2Java and Java2WSDL tools are not
> creating the return types that our application needs.  Here's the
> underlying issue...
>
> Is it possible to return a custom object array instead of a
> java.util.List?

Hmm...   The answer seems to be no, but this is per spec.  I THOUGHT a 
jaxb customization might work (<jxb:globalBindings 
collectionType="indexed"/>) and that does make any of the collections in 
the types (like any collection in the StockQuote object) be changed from 
a List to an array.   However, that has no impact on the jaxws generated 
stuff (port type interface).     I checked the RI and it generates the 
same as CXF.  I also checked the JAX-WS spec and that doesn't make any 
allowance for making that an array.  The parts generated on the 
interface need to be the collections.

I guess my suggestion would be to not bother running wsdl2java at all.   
Use the same interface/objects on the client side as you do on the 
server side.   Move the StockQuoteService interface and all the types it 
needs into a shared jar.  

Note: the RequestWrapper and ResponseWrapper annotations are wrong.  They 
should point to classes that would implement the wrapper types.  Like a 
GetQuotes.java.     My suggestion is to just eliminate those 
annotations.   For CXF, they aren't needed at all.


Dan


> Here's the example class I have that returns a collection of objects.
> With everything I've read and tried it looks like the CXF Java2WSDL
> and WSDL2Java classes doesn't build a wsdl with the correct element
> and sequence tree in order for the WSDL2Java to build the correct
> service stub.  Any help is greatly appreciated.
>
>
> Here's my class examples...
>
>
> Interface class:
> package com.cifrato.external.ws;
>
>
> import com.cifrato.data.wrapper.StockQuote;
>
>
> import javax.jws.WebService;
> import javax.jws.WebParam;
> import javax.jws.WebResult;
> import javax.jws.WebMethod;
> import javax.xml.ws.RequestWrapper;
> import javax.xml.ws.ResponseWrapper;
> import javax.jws.soap.SOAPBinding;
> import javax.jws.soap.SOAPBinding.Style;
> import javax.jws.soap.SOAPBinding.Use;>
>
>
> @SOAPBinding(style=Style.DOCUMENT,use=Use.LITERAL)
> @WebService(name="StockQuoteServicePortType")
> public interface StockQuoteService {
>             @RequestWrapper(className="java.lang.String")
>
> @ResponseWrapper(className="com.cifrato.data.wrapper.StockQuote")
>             @WebResult(name="StockQuote")
>             @WebMethod(operationName="getQuotes",exclude=false)
>             public StockQuote[] getQuotes(@WebParam(name = "symbols")
> String[] symbols);
>
> }
>
>
>
>
>
> Implementation class:
> package com.cifrato.external.ws;
>
>
>
> import com.cifrato.data.wrapper.StockQuote;
>
> public class StockQuoteServiceImpl implements StockQuoteService {
>
>
>
>             public StockQuote[] getQuotes(String[] symbols) {
>                         StockQuote[] quotes = null;
>                         if (symbols != null && symbols.length != 0) {
>                                     quotes = new
> StockQuote[symbols.length];
>                                     for (int i = 0; i <
> symbols.length; i++) {
>
> quotes[i].setSymbol(symbols[i]);
>                                                 quotes[i].setPrice(i +
> 1 * 5);
>                                     }
>                         } else {
>                                     quotes = new StockQuote[2];
>                                     quotes[0].setSymbol("IBM");
>                                     quotes[0].setPrice(50);
>                                     quotes[1].setSymbol("MSFT");
>                                     quotes[1].setPrice(100);
>                         }
>
>                         return quotes;
>             }
>
> }
>
>
>
>
>
> Custom object class to return as a collection:
> package com.cifrato.data.wrapper;
>
>
>
> public class StockQuote {
>
>
> 	private String symbol;
> 	private int price;
> 	public String getSymbol() {
> 		return symbol;
>
> 	}
>
>             public void setSymbol(String symbol) {
>                         this.symbol = symbol;
>
>             }
>
>             public int getPrice() {
>                         return price;
>
>             }
>
>             public void setPrice(int price) {
>                         this.price = price;
>
>             }
>
>
>
> }
>
>
>
> Build.xml:
> <?xml version="1.0"?>
> <project name="cxf-test" basedir=".">
>
>             <property environment="system" />
>             <property name="host.name" value="localhost" />
>             <property name="java.home" value="${system.JAVA_HOME}"/>
>             <property name="jetty.home" value="${system.JETTY_HOME}"
> /> <property name="hamachi.home"
> value="${system.JETTY_HOME}/hamachi" />
>
>             <echo message="${os.name}"/>
>
>
>
>     <path id="cxf.classpath">
>         <fileset dir="lib">
>             <include name="*.jar"/>
>         </fileset>
>
>     </path>
>
>
>
>             <!--
> ================================================================== -->
>
>             <!-- GENERATE WSDL FROM WEB SERVICE CLASSES FROM SERVER
> PACKAGE         -->
>
>             <!--
> ================================================================== -->
>
>             <target name="test.wsdl" depends="server"
> description="GENERATE WSDL">
>                         <delete file="test.wsdl" quiet="true"/>
>                         <delete dir="build/wsdl" quiet="true"/>
>                         <mkdir dir="build/wsdl"/>
>                         <java
> classname="org.apache.cxf.tools.java2wsdl.JavaToWSDL" fork="true">
>                                     <classpath refid="cxf.classpath"/>
>                                     <arg value="-cp"/>
>                                     <arg
> value="lib/cifrato_server.jar"/>
>                                     <arg value="-o"/>
>                                     <arg value="test.wsdl"/>
>                                     <arg value="-d"/>
>                                     <arg value="build/wsdl"/>
>                                     <arg value="-quiet"/>
>                                     <arg
> value="com.cifrato.external.ws.StockQuoteService"/>
>                         </java>
>             </target>
>
>
>
>             <!--
> ================================================================== -->
>
>             <!-- GENERATE JAVA FROM WSDL  wsdl2java -d build/classes
> -compile ./wsdl/hello_world.wsdl -->
>
>             <!--
> ================================================================== -->
>             <target name="test.stub">
>                         <copy file="build/wsdl/test.wsdl"
> todir="${basedir}" overwrite="true" />
>                         <delete
> dir="src/java/client/com/cifrato/client/external/cxf/ws"
> quiet="true"/> <mkdir
> dir="src/java/client/com/cifrato/client/external/cxf/ws"/>
>                         <java
> classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true">
>                                     <classpath refid="cxf.classpath"/>
>                                     <arg value="-client" />
>                                     <arg value="-p" />
>                                     <arg
> value="com.cifrato.client.external.cxf.ws"/>
>                                     <arg value="-d" />
>                                     <arg value="src/java/client" />
>                                     <arg value="${basedir}/test.wsdl"
> /> </java>
>             </target>
>
> </project>



-- 
J. Daniel Kulp
Principal Engineer, IONA
dkulp@apache.org
http://www.dankulp.com/blog