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