Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB workaround for Chameleon XSD imports?

Tags:

java

xml

jaxb

xsd

this is my first question, so please be gentle ;)

I'm stuck with a weird problem. Essentially i get three XSD definitions like the following:

PartA.xsd
targetNameSpace="PartA"
include="PartB.xsd"

PartB.xsd
<!-- no namespace definition!!! -->

PartC.xsd
targetNameSpace="PartC"
inlude="PartB.xsd"
import="PartA.xsd"

The error pops up, when binding PartC via JAXB to Java classes:

  • A class/interface with the same name "b.exampleType" is already in use. Use a class customization to resolve this conflict.
  • This confusing error happened most likely because the schema uses a technique called "chameleon schema", which causes a single definition to be loaded multiple times into different namespaces. See http://forums.java.net/jive/thread.jspa?threadID=18631 for more about this.

Following the link, i found out, the actual error lies in PartB, which has no namespace declaration! This method is called Chameleon Schema. The defined types in PartB will adopt the namesspace of the importing XSD.

So in my case, there are two namespaces for the same type:

  1. "PartA"
  2. "PartC"

And this is, where JAXB breaks down. I haven't found a way to bind PartC properly. And (to make things tricky) i have chance to change the original XSD definitions!

Has anyone come across this phenomena or something like that before and has a valid workaround for it?

like image 864
Gruber Avatar asked Oct 20 '10 08:10

Gruber


3 Answers

I was having the same issue and the google search landed me here. Your question is detailed enough and I was able to find the answer, what I did is put the namespace in PartB.xsd and use XJC to generate the java classes. I added the following:

xmlns:ns="http://www.myCompany.com/2009/01/CustSchema" targetNamespace="http://www.myCompany.com/2009/01/CustSchema"

like image 35
vamsi-vegi Avatar answered Oct 26 '22 23:10

vamsi-vegi


The following is available, although it does not provide a lot of detail:

  • https://javaee.github.io/jaxb-v2/doc/user-guide/ch03.html#compiling-xml-schema-how-modularization-of-schema-interacts-with-xjc
like image 44
bdoughan Avatar answered Oct 26 '22 23:10

bdoughan


I was facing the same problem using wsdl2java:

WSDLToJava Error: Thrown by JAXB : A class/interface with the same name "Respuesta" is already in use. Use a class customization to resolve this conflict.

But this question pointed me in the right direction. Using wsdl2java from CFX you can customize how elements are binded to classes using a binding.xml file. For example:

/Applications/apache-cxf-2.7.13/bin/wsdl2java -b ./src/main/resources/binding.xml -V -d src/main/java -compile -classdir target/classes  http://someurl.wsdl

The key is to explain in the binding.xml to name certain xsd element with one especific className to avoid colissions:

<jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1">

  <jxb:bindings schemaLocation="./someXsdFile.xsd">
    <!-- Rename the respuesta class to resolve a naming conflict with other Respuesta element already defined-->
    <jxb:bindings node="//xs:element[@name='respuesta']/xs:complexType">
      <jxb:class name="Respuesta2" />
    </jxb:bindings>
  </jxb:bindings>
</jxb:bindings>

Hope this helps to the next person with this problem using wsdl2java. I supose that other tools should allow similar aproaches to this problem.

like image 66
Ricardo Vila Avatar answered Oct 27 '22 00:10

Ricardo Vila