jax-ws import and customizing package to namespace mapping - java

How do I customize the packages of the namespaces when using jax-ws to generate the java artifacts.
I'm running jax-ws iwsmport via maven.
I don't want to change the default package, I want to be able to map from more than one namespace to different packages.

<jaxb:bindings
schemaLocation="../../wscontract/src/main/resources/wsdl/address.xsd"
node="//xsd:schema[#targetNamespace='http://demo.iae.ws/address']">
<jaxb:schemaBindings>
<jaxb:package name="demo.ws.address" />
<jaxb:nameXmlTransform>
<jaxb:typeName prefix="Customer" />
</jaxb:nameXmlTransform>
</jaxb:schemaBindings>
</jaxb:bindings>
Use JAXB bindings with the wsimport -b switch. You can find some sample files here.

Related

Is this offical Xml schema invalid or is error limitation of Jaxb

uPnP defines a number of Xml schemas including didl-lite.xsd, including this section:
<xsd:sequence>
<xsd:element ref="dc:title"/>
<xsd:group ref="didl-lite:allowed-under-container" minOccurs="0" maxOccurs="unbounded"/>
<xsd:group ref="upnp:class.group"/>
<xsd:group ref="didl-lite:allowed-under-container" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
When I tried to build Java classes from this using jaxb it complained
Removing the second xsd:group ref="didl-lite:allowed-under-container" minOccurs="0" maxOccurs="unbounded" line so we have
<xsd:sequence>
<xsd:element ref="dc:title"/>
<xsd:group ref="didl-lite:allowed-under-container" minOccurs="0" maxOccurs="unbounded"/>
<xsd:group ref="upnp:class.group"/>
</xsd:sequence>
fixed the issue, and seems to make more sense.
But I am not clear is the Xsd actually invalid or is this just a limitation of generating Jaxb classes from Xsd?
I think both semantically and formally the schema provided is valid.
You can, for instance, verify the schema well-formedness with Java or online, for example, in this site.
The issue you are facing could be considered a kind of limitation of JAXB.
The limitation consists in that the generator encounters a value that has been already taken into consideration in the process of generating your classes, and it has a problem, because it will be unable to generate a property and the corresponding related methods and stuff for this second value because the names are already taken.
I will use the xjc tool for code generation but the solution should be portable to the Maven or Gradle plugins too.
If you run the xjc tool like this:
xjc -d out didl-lite-v2.xsd
the error description will give you a possible solution:
[ERROR] Property "AllowedUnderItem" is already defined. Use <jaxb:property> to resolve this conflict
The mentioned term <jaxb:property> has to do with JAXB XML bindings.
JAXB XML bindings allows you to customize the JAXB Java classes generation process in different ways.
The necessary configuration is provided in a XML file with a certain information.
In this specific use case, you can define the following bindings XML file, let's name it binding.xml:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:bindings schemaLocation="didl-lite-v2.xsd">
<jaxb:bindings
node="//xsd:complexType[#name='container.type']/xsd:sequence/xsd:group[#ref='didl-lite:allowed-under-container'][2]">
<jaxb:property name="allowedUnderContainerAfterUpnpClassGroup"/>
</jaxb:bindings>
<jaxb:bindings
node="//xsd:complexType[#name='item.type']/xsd:sequence/xsd:group[#ref='didl-lite:allowed-under-item'][2]">
<jaxb:property name="allowedUnderItemAfterUpnpClassGroup"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
As you can see, we are indicating that the second occurrence of the allowed-under-item group, represented by the XPath expression //xsd:complexType[#name='item.type']/xsd:sequence/xsd:group[#ref='didl-lite:allowed-under-item'][2], should be treated as allowedUnderItemAfterUpnpClassGroup. We need to do something similar with allowed-under-container.
Then, if you run again the xjc tool passing in this XML bindings file, your classes will be generated successfully:
xjc -d out -b binding.xml didl-lite-v2.xsd
This or this other SO questions could be of help as well.

Spring Jaxb2Marshaller External Binding File

In Spring, I'm declaring my org.springframework.oxm.jaxb.Jaxb2Marshaller, but I also want to declare an external binding file:
<bean id="myMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="com.path.to.pojos" />
<property name="jaxbContextProperties">
<util:map>
<entry key="eclipselink.oxm.metadata-source">
<list>
<value>com/path/to/schema/binding.xjb</value>
</list>
</entry>
</util:map>
</property>
<property name="schema" value="classpath:com/path/to/schema/myService.xsd"/>
</bean>
My binding file looks like this:
<jaxb:bindings version="1.0"
jaxb:version="2.0"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:annox="http://annox.dev.java.net"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc annox">
<jaxb:bindings schemaLocation="myService.xsd" node="/xs:schema">
<jaxb:globalBindings>
<xjc:javaType name="java.util.Date" xmlType="xs:date"
adapter="com.some.path.to.custom.adapter.DateAdapter" />
</jaxb:globalBindings>
<!-- More Declarations -->
</jaxb:bindings>
</jaxb:bindings>
This setup works fine with XJC to generate the objects from the schema along with the external binding file. But I can't get the appropriate setup for my Spring configuration.
I get the following error:
org.xml.sax.SAXParseException; lineNumber: 9; columnNumber: 77; unexpected element (uri:"http://java.sun.com/xml/ns/jaxb", local:"bindings"). Expected elements are <{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-schema>,<{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-schema-type>,<{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-schema-types>,<{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-java-type-adapters>,<{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-registries>,<{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}xml-enums>,<{http://www.eclipse.org/eclipselink/xsds/persistence/oxm}java-types>
I'm stuck on this, and I really need the binding file to be separate than my schema. I can't find any example of this setup online, I would love an example on how to properly configure an external binding file with the JaxB2Marshaller.
Please let me know if my question is incomplete or if more information is required.
Thanks,
JP
As far as I know, bindings file is only used during the compilation time, to derive Java classes from the XML Schema. So it does not make sense to configure it in runtime, on a marshaller. Neither Spring nor JAXB will consider it. All you could have configured with the bindings file is already in your com.path.to.pojos.* classes.

CXF wsdl2java - mapping namespaces and packages

I'm using CXF's wsdl2java tool to create a java web service.
I have a wsdl file and a few XSD files and I know that it's possible to use a binding file to map namespaces and packages. My binding file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" jaxb:version="2.0">
<jaxb:bindings schemaLocation="SchemeA.xsd" node="/xsd:schema">
<jaxb:schemaBindings>
<jaxb:package name="com.test.package.a" />
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="SchemeB.xsd" node="/xsd:schema">
<jaxb:schemaBindings>
<jaxb:package name="com.test.package.b" />
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="SchemeC.xsd" node="/xsd:schema">
<jaxb:schemaBindings>
<jaxb:package name="com.test.package.c" />
</jaxb:schemaBindings>
</jaxb:bindings>
</jaxb:bindings>
My files:
A.wsdl (imports all .xsd files)
SchemeA.xsd
SchemeB.xsd
SchemeC.xsd
It works great for everything in this XSD schemes but not for wsdl's definition. I mean at the end my packages looks like this:
com.test.package.a
com.test.package.b
com.test.package.c
https.package_test_com.a.service
The last line bother me, and I would like it to look like this: com.test.package.a.service
The binding file is used by jaxb that manages bindings of paramater and responses but webservice is directly managed by cxf or jax-ws so you will need to specify this binding with -p option of wsdl2java as specified here http://cxf.apache.org/docs/wsdl-to-java.html

adding an annotation to a JAXB binding class from a schema

Hi stackoverflow world,
I want to specify in a XSD that a specific element can be used as a XmlRootElement by JAXB.
I know how to add the annotation to the generated class: what I want to do is to specify that a element can be generated as a root element before the code generation.
I use external JAXB customizations (.xjb files).
The purpose is here to not modifying the schemas (as they are defining standards).
Anybody knows how do that?
Thanks!
NJ
Problem solved.
The JAXB plugin Annotate http://confluence.highsource.org/display/J2B/Annotate+Plugin do the job.
Add the following fragment in your jaxb binding file (external binding, i.e. a .xjb file):
<jaxb:bindings schemaLocation="csw/2.0.2/CSW-discovery.xsd" node="/xs:schema">
<jaxb:bindings node="xs:complexType[#name='GetRecordsType']">
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
name="GetRecordsType" />
</annox:annotate>
</jaxb:bindings>
</jaxb:bindings>
Do not forget to declare the namespaces:
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:annox="http://annox.dev.java.net"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
jaxb:extensionBindingPrefixes="xjc annox" version="2.1">
...
</jaxb:bindings>
And use a ANT or MAVEN task http://confluence.highsource.org/display/J2B/User+Guide to proceed the generation of the sources.
I still search how to specify manually (without an xjc task with ant or maven) the JAXB extensions but it works now. (I have my own ANT script what's why I search to manually call XJC).
The JAXB extension mechanism is very convenient, have a look to JAXB2 Basics:
http://confluence.highsource.org/display/J2B/Home

Error using jaxb external bindings customization

I use the wsdlc tool (weblogic 10.3.1) to generate classes from wsdl.
I have the following external jaxb bindings customization file:
<jaxb:bindings
xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
schemaLocation="web/WEB-INF/....xsd"
version="2.1">
<jaxb:bindings node="/xs:schema">
<jaxb:globalBindings>
<xjc:superClass name="my.MySuperClass" />
</jaxb:globalBindings>
</jaxb:bindings>
</jaxb:bindings>
The error message on complilation is: cannot find symbol my.MySuperClass.
And from javac: "package my does not exist". The classpath = everything I include via <pathelement location= etc. and 60 lines from eclipse plugins. The problem lies in the javac command that wsdlc initiates. The classpath of this command is correct (hard coded paths e.g.) but still "package ... does not exist".
The usage of wsdlc from ant is like so:
<path id="class.path">
<pathelement path="${java.class.path}" />
<pathelement location="... hard coded path on disk to a jar" />
</path>
<target name="generate-ws-from-wsdl">
<wsdlc failOnError="true"
srcWsdl="${basedir}/web/WEB-INF/ps.wsdl"
destImplDir="${basedir}/src"
destJwsDir="${basedir}/web/WEB-INF/lib"
srcPortName="PsPort"
type="JAXWS">
<binding file="jaxb-bindings.xml" />
<classpath refid="class.path" />
</wsdlc>
</target>
my.SuperClass has to exist already, wsdlc won't generate it for you. When it comes to compiling the generated code (which is where I assume is what is failing here), it's because javac can't find my.SuperClass in its classpath.
Please provide the excerpt of the build.xml showing how you use use the wsdlc.
According to the documentation:
In addition to the WebLogic-specific
wsdlc attributes, you can also define
the following standard javac
attributes; see the Ant documentation
for additional information about each
attribute:
bootclasspath
bootClasspathRef
classpath
[...]
You can also use the following
standard Ant child elements with the
wsdlc Ant task:
<FileSet>
<SourcePath>
<Classpath>
Did you specify the classpath to include my.SuperClass?
I didn't jar my classes properly, I thought I could use WinZip to quickly add some classes to a jar, but the 'path' in WinZip was not equal to the package name in java. It took me a while but I learned something about classpaths.

Categories