Dan, Sorry, I just spotted that there were some other response e-mails on nabble.com's archive of this mailing list (http://www.nabble.com/Problem-generating-WSDL-from-Java-API-with- CXF-2.0.3-td15084730.html lists this thread) which I didn't actually get. Not sure why. Were you asking for me to provide some debug output from the java2wsdl when I don't have the additional annotations on the nested usages of the API interfaces or were you responding to Marc? (I think it was the latter.)
I've switched over to using List<TheInterface> with an appropriate XmlJavaTypeAdapter on TheInterface to an implementation of that interface (it's a shame I have to expose the implementations in the same source tree) and that seems to generate the WSDL fine (with appropriate @XmlType(name = "TheInterface") annotations on the implementations)... I still have to actually try to invoke the service to see if marshalling and unmarshalling work! I've applied the @XmlElement(required = true) annotation where I can, but this can only be applied to properties/fields. I still don't know how to force an operation/method parameter to be required in the WSDL/XSD generated... any suggestions (the WebParam annotation strangely has no way of controlling this)? Phil :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 > > >