Hi,
Have you tried using a List instead of an array for your return value?

Do you have a demo project that I could reference?
I have tried the annotation of interfaces and have had it work sporadically.  I 
just received a "org.apache.cxf.interceptor.Fault: Marshalling Error: 
com.rulestream.core.knowledge.domain.MyClass is not known to this context" 
exception.
Before this exception, I could not initialize the web service.

Regards,
Marc


-----Original Message-----
From: Phil Weighill-Smith [mailto:[EMAIL PROTECTED]
Sent: Monday, January 28, 2008 12:20 PM
To: Daniel Kulp
Cc: cxf-user@incubator.apache.org
Subject: Re: Problem generating WSDL from Java API with CXF 2.0.3

Dan,

What I've found so far is that I can declare myself a new adapter, e.g.:

    public final class SimpleThingArrayAdapter extends
            XmlAdapter<SimpleThingImpl[], SimpleThing[]> {
        @Override
        public SimpleThingImpl[] marshal(SimpleThing[] simpleThings)
                throws Exception {
            if (simpleThings instanceof SimpleThingImpl[]) {
                return (SimpleThingImpl[]) simpleThings;
            } else {
                SimpleThingImpl[] result =
                        new SimpleThingImpl[simpleThings.length];
                System.arraycopy(simpleThings, 0,
                                 result, 0,
                                 simpleThings.length);
                return result;
            }
        }

        @Override
        public SimpleThing[] unmarshal(SimpleThingImpl[] simpleThings)
                throws Exception {
            return simpleThings;
        }
    }

and then assign this against the web method, e.g.:

    @WebResult(name = "result",
               targetNamespace = Namespace.URI)
    @XmlJavaTypeAdapter(type = SimpleThing[].class, value = 
org.bad.jaxb.SimpleThingArrayAdapter.class)
    SimpleThing[] getThingsThatMatch(
            @WebParam(name = "namePattern")
            final String namePattern);

This then gets rid of the error... I think. Not finished sorting this
out though...

If I hit a dead end I'll look see if 2.1 helps.

Thanks again,

Phil :n.

On Mon, 2008-01-28 at 11:41 -0500, Daniel Kulp wrote:
> On Monday 28 January 2008, Phil Weighill-Smith wrote:
> > I'm trying to apply the pattern I described earlier to my real world
> > scenario. The problem I haven't figured out a way round is when I have
> > parameters and return types based on arrays of the interfaces. I get
> > an annotation error with JAXB complaining it can't handle interfaces
> > (despite having the required @XmlJavaTypeAdapter against the interface
> > itself). I've tried repeating the @XmlJavaTypeAdapter definition as
> > part of the web method signature but that doesn't seem to work.
>
> That will only work with JAX-WS 2.1 and thus CXF 2.1 snapshots.  And even
> then I'm not sure if we have that working in the snapshots yet.
>
> Not sure what to suggest.   I'm wondering if it's not finding the "impl"
> that goes with it.   With 2.1, I'd suggest adding an @XmlSeeAlso
> annotation to make sure the impl gets pulled in.   Maybe try a
> jaxb.index file in the package that just has the line "SimpleThinkImpl"
> or similar to make sure the impl gets sucked into the context creation.
>
> It might just be a bug in jaxb.   I'd honestly suggest trying with the
> CXF 2.1 snapshots to see if it works there.   2.1 uses the latest JAXB
> 2.1 version which may have a lot more issues fixed.
>
> Dan
>
>
>
>
> >
> > Do I need to provide an adapter for the array type? (I'll give that a
> > try, I guess.)
> >
> > Phil :n(
> >
> > PS: If I ever find time, I'm sure I could extend the SimpleService
> > example to cover these awkward aspects and to get it to a working
> > example state... don't hold your breath though! ;n)
> >
> > On Mon, 2008-01-28 at 10:31 -0500, Daniel Kulp wrote:
> > > That's very cool.   This is something I'd actually like to see a
> > > complete project/build/example for as a tutorial or something if you
> > > can get it working.
> > >
> > > >   * whether the various parameters and results can be "null" (i.e.
> > > > I would like to change the minOccurs="0" to minOccurs="1" - the
> > > > default for XML Schema)
> > >
> > > In the SimpleThingImpl, on the getters or on the fields, add:
> > > @XmlElement(required = true)
> > >
> > > >       * ensuring that the generated complex types have all
> > > > elements in the required namespace (the schema has
> > > > elementFormDefault as "unqualified", whilst I'd like them to be
> > > > qualified)
> > >
> > > Two options:
> > > 1) And @XmlElement annotations to everything and fill in namespaces
> > > for them
> > >
> > > 2) Create a package-info.java class in the package containing the
> > > beans. It would look like:
> > >
> > > @javax.xml.bind.annotation.XmlSchema(
> > >      namespace = "http://the.namespace.to.use";,
> > >      elementFormDefault =
> > > javax.xml.bind.annotation.XmlNsForm.QUALIFIED) package the package;
> > >
> > > >       * ensuring the WSDL contains appropriate documentation.
> > >
> > > THAT is something I don't know if it's possible.   You'd probably
> > > have to ask on the JAXB list about that.
> > >
> > > Dan
> > >
> > > > Any ideas how to address these?
> > >
> > > On Monday 28 January 2008, Phil Weighill-Smith wrote:
> > > > Dan/anyone else,
> > > >
> > > > I've got further (not sure if it will actually work with JAXB
> > > > marshalling and unmarshalling, will find out later today) whilst
> > > > still using interfaces as part of my API - the WSDL now looks
> > > > more-or-less OK.
> > > >
> > > > The extra steps I've taken, as previously partially outlined, are
> > > > to:
> > > >
> > > >       * provide a "simple" implementation of the interface, but
> > > > one that supplies setters too
> > > >       * provide an XmlJavaTypeAdapter annotation against the
> > > > SimpleThing interface, and supply the XmlAdapter implementation to
> > > > adapt between the interface and the "simple" mutable
> > > > implementation * annotate the implementation to set the XmlType
> > > > name to the interface name so the WSDL looks sensible
> > > >
> > > > So my SEI looks unchanged, but the following is added/modified:
> > > >
> > > > /**
> > > >  * A simple thing to communicate over the web service.
> > > >  */
> > > > @XmlJavaTypeAdapter(SimpleThingAdapter.class)
> > > > public interface SimpleThing {
> > > >     ...
> > > >
> > > > Plus:
> > > >
> > > > /**
> > > >  * Simple but mutable implementation of [EMAIL PROTECTED] SimpleThing}.
> > > >  */
> > > > @XmlType(name = "SimpleThing")
> > > > public class SimpleThingImpl implements SimpleThing {
> > > >     // The name of this instance
> > > >     private String name;
> > > >
> > > >     // The description of this instance
> > > >     private String description;
> > > >
> > > >     @Override
> > > >     public String getName() {
> > > >         return name;
> > > >     }
> > > >
> > > >     /**
> > > >      * Sets or resets the name of this instance.
> > > >      *
> > > >      * @param name the new value for the name
> > > >      */
> > > >     public void setName(final String name) {
> > > >         this.name = name;
> > > >     }
> > > >
> > > >     @Override
> > > >     public String getDescription() {
> > > >         return description;
> > > >     }
> > > >
> > > >     /**
> > > >      * Sets or resets the description for this instance.
> > > >      *
> > > >      * @param description the new value for the description
> > > >      */
> > > >     public void setDescription(final String description) {
> > > >         this.description = description;
> > > >     }
> > > > }
> > > >
> > > > And finally:
> > > >
> > > >     class SimpleThingAdapter extends XmlAdapter<SimpleThingImpl,
> > > > SimpleThing> { @Override
> > > >         public SimpleThingImpl marshal(SimpleThing simpleThing)
> > > >                 throws Exception {
> > > >             return (SimpleThingImpl) simpleThing;
> > > >         }
> > > >
> > > >         @Override
> > > >         public SimpleThing unmarshal(SimpleThingImpl simpleThing)
> > > >                 throws Exception {
> > > >             return simpleThing;
> > > >         }
> > > >     }
> > > >
> > > > With a Document, Literal, Wrapped binding I get the following
> > > > WSDL:
> > > >
> > > > <?xml version="1.0" encoding="UTF-8"?>
> > > > <wsdl:definitions name="SimpleServiceService"
> > > > targetNamespace="http://org.bad";
> > > > xmlns:ns1="http://org.bad.SimpleService/service";
> > > > xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/";
> > > > xmlns:tns="http://org.bad";
> > > >                   xmlns:xsd="http://www.w3.org/2001/XMLSchema";
> > > >
> > > > xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/";> <wsdl:types>
> > > >         <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
> > > >
> > > > xmlns:tns="http://org.bad.SimpleService/service";
> > > > attributeFormDefault="unqualified"
> > > >                    elementFormDefault="unqualified"
> > > >
> > > > targetNamespace="http://org.bad.SimpleService/service";>
> > > > <xs:element name="getThing" type="tns:getThing"/> <xs:element
> > > > name="getThingResponse" type="tns:getThingResponse"/>
> > > > <xs:complexType name="getThing">
> > > >                 <xs:sequence>
> > > >                     <xs:element minOccurs="0" name="name"
> > > > type="xs:string"/> </xs:sequence>
> > > >             </xs:complexType>
> > > >             <xs:complexType name="getThingResponse">
> > > >                 <xs:sequence>
> > > >                     <xs:element minOccurs="0" name="result"
> > > >                                 type="tns:SimpleThing"/>
> > > >                 </xs:sequence>
> > > >             </xs:complexType>
> > > >             <xs:complexType name="SimpleThing">
> > > >                 <xs:sequence>
> > > >                     <xs:element minOccurs="0" name="description"
> > > >                                 type="xs:string"/>
> > > >                     <xs:element minOccurs="0" name="name"
> > > > type="xs:string"/> </xs:sequence>
> > > >             </xs:complexType>
> > > >         </xs:schema>
> > > >     </wsdl:types>
> > > >     <wsdl:message name="getThing">
> > > >         <wsdl:part name="parameters" element="ns1:getThing">
> > > >         </wsdl:part>
> > > >     </wsdl:message>
> > > >     <wsdl:message name="getThingResponse">
> > > >         <wsdl:part name="parameters"
> > > > element="ns1:getThingResponse"> </wsdl:part>
> > > >     </wsdl:message>
> > > >     <wsdl:portType name="SimpleService">
> > > >         <wsdl:operation name="getThing">
> > > >             <wsdl:input name="getThing" message="ns1:getThing">
> > > >             </wsdl:input>
> > > >             <wsdl:output name="getThingResponse"
> > > >                          message="ns1:getThingResponse">
> > > >             </wsdl:output>
> > > >         </wsdl:operation>
> > > >     </wsdl:portType>
> > > >     <wsdl:binding name="SimpleServiceServiceSoapBinding"
> > > >                   type="ns1:SimpleService">
> > > >         <soap:binding style="document"
> > > >
> > > > transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation
> > > > name="getThing">
> > > >             <soap:operation soapAction="" style="document"/>
> > > >             <wsdl:input name="getThing">
> > > >                 <soap:body use="literal"/>
> > > >             </wsdl:input>
> > > >             <wsdl:output name="getThingResponse">
> > > >                 <soap:body use="literal"/>
> > > >             </wsdl:output>
> > > >         </wsdl:operation>
> > > >     </wsdl:binding>
> > > >     <wsdl:service name="SimpleServiceService">
> > > >         <wsdl:port name="SimpleServicePort"
> > > >                    binding="ns1:SimpleServiceServiceSoapBinding">
> > > >             <soap:address location="http://localhost:9090/hello"/>
> > > >         </wsdl:port>
> > > >     </wsdl:service>
> > > > </wsdl:definitions>
> > > >
> > > > The only things I still can't control are:
> > > >
> > > >       * whether the various parameters and results can be "null"
> > > > (i.e. I would like to change the minOccurs="0" to minOccurs="1" -
> > > > the default for XML Schema)
> > > >       * ensuring that the generated complex types have all
> > > > elements in the required namespace (the schema has
> > > > elementFormDefault as "unqualified", whilst I'd like them to be
> > > > qualified) * ensuring the WSDL contains appropriate documentation.
> > > >
> > > > Any ideas how to address these?
> > > >
> > > > Phil :n.
> > > >
> > > > On Fri, 2008-01-25 at 11:50 -0500, Daniel Kulp wrote:
> > > > > JAXB generally doesn't like interfaces too much.  In general, we
> > > > > definitely suggest using concrete classes.
> > > > >
> > > > > That said, one major issue is that your interface doesn't have
> > > > > setter methods on it.   There's no way there's any chance of it
> > > > > working without that.   JAXB would only expose properties that
> > > > > have bother getters and setters.   That said, I still doubt it
> > > > > will work as interfaces.   The jaxws spec really doesn't allow
> > > > > for that at all.   Just concrete data objects.
> > > > >
> > > > > Dan
> > > > >
> > > > > On Friday 25 January 2008, Phil Weighill-Smith wrote:
> > > > > > For some reason I can't get CXF 2.0.3 to generate what looks
> > > > > > like correct WSDL from a set of Java interfaces. I either get
> > > > > > no XML representing the object(s) or get an abstract complex
> > > > > > type for the object(s) depending on the interfaces involved.
> > > > > >
> > > > > > Here's a simple example. Because I use interfaces for the
> > > > > > returned object(s) I have a factory. This looks like:
> > > > > >
> > > > > > package org.bad;
> > > > > >
> > > > > > /**
> > > > > >  * A simple factory to allow JAXB to handle the various
> > > > > > interfaces used. */
> > > > > > public class SimpleFactory {
> > > > > >     /**
> > > > > >      * Support the [EMAIL PROTECTED] SimpleThing} class.
> > > > > >      *
> > > > > >      * @return a SimpleThing implementation. Added setters for
> > > > > > good luck not *         knowing just how JAXB should handle
> > > > > > unmarshalling */
> > > > > >     public SimpleThing createSimpleThing() {
> > > > > >         return new SimpleThing() {
> > > > > >             /**
> > > > > >              * The description.
> > > > > >              */
> > > > > >             private String description = null;
> > > > > >
> > > > > >             /**
> > > > > >              * The name.
> > > > > >              */
> > > > > >             private String name = null;
> > > > > >
> > > > > >             @Override
> > > > > >             public String getDescription() {
> > > > > >                 return description;
> > > > > >             }
> > > > > >
> > > > > >             @Override
> > > > > >             public String getName() {
> > > > > >                 return name;
> > > > > >             }
> > > > > >
> > > > > >             /**
> > > > > >              * Allow the description to be modified.
> > > > > >              *
> > > > > >              * @param description the new description
> > > > > >              */
> > > > > >             public void setDescription(String description) {
> > > > > >                 this.description = description;
> > > > > >             }
> > > > > >
> > > > > >             /**
> > > > > >              * Allow the name to be modified.
> > > > > >              *
> > > > > >              * @param name the new name
> > > > > >              */
> > > > > >             public void setName(String name) {
> > > > > >                 this.name = name;
> > > > > >             }
> > > > > >         };
> > > > > >     }
> > > > > > }
> > > > > >
> > > > > > I then have the SimpleThing (the object to be returned)
> > > > > > defined as:
> > > > > >
> > > > > > package org.bad;
> > > > > >
> > > > > > import javax.xml.bind.annotation.XmlType;
> > > > > >
> > > > > > /**
> > > > > >  * A simple thing to communicate over the web service.
> > > > > >  */
> > > > > > @XmlType(factoryClass = SimpleFactory.class,
> > > > > >          factoryMethod = "createSimpleThing")
> > > > > > public interface SimpleThing {
> > > > > >     /**
> > > > > >      * A read-only name property.
> > > > > >      *
> > > > > >      * @return the name property
> > > > > >      */
> > > > > >     String getName();
> > > > > >
> > > > > >     /**
> > > > > >      * A read-only description property.
> > > > > >      *
> > > > > >      * @return the description property
> > > > > >      */
> > > > > >     String getDescription();
> > > > > > }
> > > > > >
> > > > > > Finally, the service is then defined thus:
> > > > > >
> > > > > > package org.bad;
> > > > > >
> > > > > > import javax.jws.WebService;
> > > > > > import javax.jws.WebParam;
> > > > > > import javax.jws.WebResult;
> > > > > > import javax.jws.soap.SOAPBinding;
> > > > > >
> > > > > > /**
> > > > > >  * The SEI java class.
> > > > > >  */
> > > > > > @WebService(name = "SimpleService",
> > > > > >             targetNamespace =
> > > > > > "http://org.bad.SimpleService/service";) @SOAPBinding(style =
> > > > > > SOAPBinding.Style.RPC,
> > > > > >              use = SOAPBinding.Use.ENCODED,
> > > > > >              parameterStyle =
> > > > > > SOAPBinding.ParameterStyle.WRAPPED) public interface
> > > > > > SimpleService {
> > > > > >     /**
> > > > > >      * Get a [EMAIL PROTECTED] SimpleThing} by name.
> > > > > >      *
> > > > > >      * @param name the name for the [EMAIL PROTECTED] SimpleThing} 
> > > > > > to be
> > > > > > returned. * @return the [EMAIL PROTECTED] SimpleThing} with that 
> > > > > > name, or
> > > > > > null if there isn't a
> > > > > >      *         match
> > > > > >      */
> > > > > >     @WebResult(name = "result",
> > > > > >                targetNamespace =
> > > > > > "http://org.bad.SimpleService";) SimpleThing getThing(
> > > > > >             @WebParam(name = "name")
> > > > > >             final String name);
> > > > > > }
> > > > > >
> > > > > > When I run the java2wsdl (via the IDEA's Web Services
> > > > > > integration mechanism) I get the following output:
> > > > > >
> > > > > > <?xml version="1.0" encoding="UTF-8"?>
> > > > > > <wsdl:definitions name="SimpleServiceService"
> > > > > > targetNamespace="http://org.bad";
> > > > > >
> > > > > > xmlns:ns1="http://org.bad.SimpleService/service";
> > > > > > xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/";
> > > > > > xmlns:tns="http://org.bad";
> > > > > >                   xmlns:xsd="http://www.w3.org/2001/XMLSchema";
> > > > > >
> > > > > > xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/";>
> > > > > > <wsdl:message name="getThing">
> > > > > >         <wsdl:part name="name" type="xsd:string">
> > > > > >         </wsdl:part>
> > > > > >     </wsdl:message>
> > > > > >     <wsdl:message name="getThingResponse">
> > > > > >         <wsdl:part name="result">
> > > > > >         </wsdl:part>
> > > > > >     </wsdl:message>
> > > > > >     <wsdl:portType name="SimpleService">
> > > > > >         <wsdl:operation name="getThing">
> > > > > >             <wsdl:input name="getThing"
> > > > > > message="ns1:getThing"> </wsdl:input>
> > > > > >             <wsdl:output name="getThingResponse"
> > > > > >                          message="ns1:getThingResponse">
> > > > > >             </wsdl:output>
> > > > > >         </wsdl:operation>
> > > > > >     </wsdl:portType>
> > > > > >     <wsdl:binding name="SimpleServiceServiceSoapBinding"
> > > > > >                   type="ns1:SimpleService">
> > > > > >         <soap:binding style="rpc"
> > > > > >
> > > > > > transport="http://schemas.xmlsoap.org/soap/http"/>
> > > > > > <wsdl:operation name="getThing">
> > > > > >             <soap:operation soapAction="" style="rpc"/>
> > > > > >             <wsdl:input name="getThing">
> > > > > >                 <soap:body use="literal"
> > > > > >
> > > > > > namespace="http://org.bad.SimpleService/service"/>
> > > > > >             </wsdl:input>
> > > > > >             <wsdl:output name="getThingResponse">
> > > > > >                 <soap:body use="literal"
> > > > > >
> > > > > > namespace="http://org.bad.SimpleService/service"/>
> > > > > >             </wsdl:output>
> > > > > >         </wsdl:operation>
> > > > > >     </wsdl:binding>
> > > > > >     <wsdl:service name="SimpleServiceService">
> > > > > >         <wsdl:port name="SimpleServicePort"
> > > > > >
> > > > > > binding="ns1:SimpleServiceServiceSoapBinding"> <soap:address
> > > > > > location="http://localhost:9090/hello"/> </wsdl:port>
> > > > > >     </wsdl:service>
> > > > > > </wsdl:definitions>
> > > > > >
> > > > > >
> > > > > > As you can see, there is no XML binding schema for SimpleThing
> > > > > > and nothing in the result from the getThing operation (in
> > > > > > bold)... what have I done wrong?
> > > > > >
> > > > > > Note that I found I could not use use the default binding
> > > > > > style (document) and use (literal) with wrapped or bare
> > > > > > parameter styles since these threw exceptions (either that the
> > > > > > wrapper classes were missing from the class path or with an
> > > > > > NPE from the generator code somewhere).
> > > > > >
> > > > > > Phil
>
>
>

Reply via email to