Spring Jaxb2Marshaller External Binding File - java

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.

Related

JAXB External Binding File Error

so I have written an external binding file for waterml2.xsd and so far have fixed the [Error] Property "Rows" is already defined and [Error] Property "Title" is already defined.
After fixing those I now am getting multiple issues dealing with collisions. For example:
[ERROR] A class/interface with the same name
"net.opengis.gml._3.SecondDefiningParameter" is already in use. Use a
class customization to resolve this conflict.
[Error] Two declarations cause a collision in the ObjectFactory class.
This is what the binding file looks like:
<bindings xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0">
<!-- In geometryPrimitives.xsd, fix so element and attribute both with name "rows" don't conflict -->
<bindings schemaLocation="http://schemas.opengis.net/gml/3.2.1/geometryPrimitives.xsd" version="3.2.1.2">
<bindings node="//xs:group/xs:sequence/xs:element[#name='rows']">
<property name="rowsElement"/>
</bindings>
</bindings>
<!-- In xlink.xsd, fix so element and attributes don't have the same "titles" conflict -->
<bindings schemaLocation="http://www.w3.org/1999/xlink.xsd" node="/xs:schema">
<schemaBindings>
<package name="net.opengis.wfs._2_1"/>
</schemaBindings>
</bindings>
<bindings schemaLocation="http://www.w3.org/1999/xlink.xsd" node="/xs:schema">
<bindings node="//xs:attributeGroup[#name='locatorAttrs']">
<bindings node=".//xs:attribute[#ref='xlink:title']">
<property name="LocatorAttrsTitle"/>
</bindings>
</bindings>
<bindings node="//xs:group[#name='locatorModel']">
<bindings node=".//xs:element[#ref='xlink:title']">
<property name="LocatorModelTitle"/>
</bindings>
</bindings>
<bindings node="//xs:attributeGroup[#name='arcAttrs']">
<bindings node=".//xs:attribute[#ref='xlink:title']">
<property name="ArcAttrsTitle"/>
</bindings>
</bindings>
<bindings node="//xs:group[#name='arcModel']">
<bindings node=".//xs:element[#ref='xlink:title']">
<property name="ArcModelTitle"/>
</bindings>
</bindings>
</bindings>
</bindings>
If anyone has any suggestions or has dealt with the WaterML 2.0 Schema before I would appreciate some help! Thanks.
The OGC schemas need a little additional binding information to correctly run through JAXB. You are a lot better off relying on the hard work at https://github.com/highsource/ogc-schemas.
To use the highsource bindings, it’s probably best to just clone the repository and use maven to build the bindings (there is good maven build support in this project). I.e.
git clone https://github.com/highsource/ogc-schemas.git
mvn install –D skipTests
I skipped the tests to speed things up and I had an issue with one test failing.
You could also just import the base pom.xml into Eclipse (or whatever IDE you use) and let the maven build go through.
Once it builds, you should end up with your bindings under the relevant folder. E.g. WaterML2.0:
ls waterml/2.0/target/generated-sources/xjc/net/opengis/waterml/v_2_0/
CategoricalTVPType.java
CategoricalTimeseriesType.java
CollectionPropertyType.java
CollectionType.java
CommentBlockPropertyType.java
and so on..
And there’s a XJB file in the target/classes folder.

xsd:include exception in soapUI:org.apache.xmlbeans.XmlException: org.apache.xmlbeans.XmlException: error: Unexpected end of file after null

I have a problem while creating new project in soapUI and importing wsdl file from URL.It gives me the below exception
Error loading [http://localhost:8080/WS/PersonalDetails.xsd]: org.apache.xmlbeans.XmlException: org.apache.xmlbeans.XmlException: error: Unexpected end of file after null
My xsd include
<xsd:include schemaLocation="PersonalDetails.xsd" />
<xsd:include schemaLocation="PersonalRequest.xsd" />
Actual Location of the xsd
WS/src/main/webapp/schemas/PersonalDetails.xsd
WS/src/main/webapp/schemas/PersonalRequest.xsd
My spring-ws.xml
<bean id="MyWSService" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition" lazy-init="true">
<property name="schemaCollection">
<bean class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
<property name="inline" value="false" />
<property name="xsds">
<list>
<value>schemas/PersonalDetailsServiceOperations.xsd</value>
</list>
</property>
</bean>
</property>
<property name="portTypeName" value="MyWSEndpoint"/>
<property name="serviceName" value="MyWS" />
<property name="locationUri" value="/"/>
</bean>
My PersonalDetailsServiceOperations.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:person="http://MyWS.com/"
targetNamespace="http://MyWS.com/"
elementFormDefault="qualified">
<xsd:include schemaLocation="PersonalDetails.xsd" />
<xsd:include schemaLocation="PersonalRequest.xsd" />
</xsd:schema>
I'm using spring+Maven+xsd+jaxb
Please help
Many Thanks
Often this happens because you're not pasting in the correct location to the WSDL into SOAP UI. When you browse to your WSDL in a browser, spring-ws will serve it up on almost any url, so long as it ends in XYZService.wsdl (or whatever you have configured it to be). The downside to this is, when you have XSD imported using relative paths inside your schema somewhere, SOAP UI tries to to resolve the relative path based on the path you gave it, but like I said, that may not actually be the real path to the WSDL.
For example, in our application we have a Spring-ws web service call ProcessService. It's served up at http://localhost:11000/ws/service/process/ProcessService.wsdl and it contains an imported XSD using relative paths. If you paste this URL into SOAP UI and run it, it correctly resolves the path to XSD. However, you can browse to http://localhost:11000/hello-world/ProcessService.wsdl and it will still serve you up the WSDL even though the URL is not correct. Now if you take http://localhost:11000/hello-world/ProcessService.wsdl and paste it into SOAP UI it won't be able to resolve the relative path to imported XSD correctly because that's not the actual URL. In this case SOAP UI gives you that exact error.
I would browse to your XSD in the browser and make sure you can see it. Then I would check the URL you are pasting into SOAP UI and see if from the relative URLs actually resolve correctly. If not, you need to give the correct path to SOAP UI.

jaxb idref string adapter

I'm using a standard xml schema, called isosts, I need to convert schema to java class using jaxb. In this xml schema, a lot of elements have attribute rid as type xs:IDREFS <xs:attribute name="rid" type="xs:IDREFS">. Jaxb converts xs:IDREFS to be list of Objects.
For my need, I want jaxb to make type xs:IDREFS to be just java string type in all the generated java class. And during marshall/unmarshall time, the value of attribute rid should all be handled as string. Since this is a standard schema, I have to customize jaxb. I'm not sure if this can be done in jaxb binding or adapter and how to do it. Can anyone help me?
This binding file (let's call it "binding.xjb) forces the type to String:
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xsi:schemaLocation=" http://java.sun.com/xml/ns/jaxb
http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
version="2.1">
<bindings schemaLocation="SomeSchemaName.xsd" node="/xs:schema">
<bindings node="//xs:attribute[#name='rid']">
<property>
<baseType>
<javaType name="java.lang.String"></javaType>
</baseType>
</property>
</bindings>
</bindings>
</bindings>
Compile the schema using
xjc -b binding.xjb SomeSchemaName.xsd

Using/converting an XML file to a Spring bean definition

I have defined a Spring application context xml which will be edited by end users to add new beans.Something like:
<bean name="myBeanName1" class="com.xxx.Yyy">
<property name="type" value="type1" />
<property name="name" value="name1" />
<property name="arguments" value="arg1" />
</bean>
<bean name="myBeanName2" class="com.xxx.Yyy">
<property name="type" value="type2" />
<property name="name" value="name2" />
<property name="arguments" value="arg2" />
</bean>
.
.
.
Now I am asked to change this to a normal xml so that users wont be bothered by bean property and class names:
<def name="Name1">
<type>type1</type>
<argument>arg1</argument
</def>
<def name="Name2">
<type>type2</type>
<argument>arg2</argument
</def>
As my code is using the bean, how can I use the new xml with minimal code change so that it is converted to a bean definition as earlier and things work as before?.
I dont know if Spring has a solution for this out of the box. What I thought was applying stylesheet to the new xml to create my older bean. Any other better/elegant solution for this?
Edit: Now that user input is not inside the bean anymore, is it possible to use the new xml to inject to a #Component class?
Spring supports creating custom tags. You need to create xsd schema, NamespaceHandlerm, implement BeanDefinitionParsers and make spring aware of these by creating spring.handlers & spring.schemas special files.
Have a look at Extensible XML authoring
Example:
<beans xmlns declaration goes here>
<yournamespace:yourcustomtag id="some id">
<yournamespace:some_other_tag your-custom-attribute="some value" />
</yournamespace:yourcustomtag>
</beans>

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

Categories