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



-- 
J. Daniel Kulp
Principal Engineer, IONA
[EMAIL PROTECTED]
http://www.dankulp.com/blog

Reply via email to