0

(I've already googled it and done a search here and found no answer, maybe I'm using the wrong keywords...)

To make it simple, I have two schemas:

a.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns="http://foo.bar/something" 
  targetNamespace="http://foo.bar/something" 
  elementFormDefault="qualified" 
  attributeFormDefault="unqualified">

  <xs:complexType name="TFoo">
    <xs:attribute name="version" type="xs:string" />
  </xs:complexType>
</xs:schema>

b.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns="http://foo.bar/something" 
  targetNamespace="http://foo.bar/something" 
  elementFormDefault="qualified" 
  attributeFormDefault="unqualified">

  <xs:complexType name="TFoo">
    <xs:attribute name="version" type="xs:string" />
    <xs:attribute name="dateTime" type="xs:dateTime" />
  </xs:complexType>
</xs:schema>

Both have the same targetNamespace and a complexType named TFoo.

I have an external binding to change the generated class name of a.xsd from TFoo to TFooA:

a-binding.xml:

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

  <jxb:bindings schemaLocation="a.xsd">
    <jxb:bindings node="//xs:complexType[@name='TFoo']">
      <jxb:class name="TFooA"/>
    </jxb:bindings>
  </jxb:bindings>

</jxb:bindings>

which works if I compile the a.xsd alone:

$ xjc -b a-binding.xml a.xsd 
parsing a schema...
compiling a schema...
bar/foo/something/ObjectFactory.java
bar/foo/something/TFooA.java
bar/foo/something/package-info.java

(look how I got TFooA.java)

But, if I try to compile both schemas at once, I get:

$ xjc -b a-binding.xml a.xsd b.xsd 
parsing a schema...
[ERROR] 'TFoo' is already defined
  line 13 of file:/home/scherrer/tmp/PL_008f/b.xsd

[ERROR] (related to above error) the first definition appears here
  line 9 of file:/home/scherrer/tmp/PL_008f/a.xsd

Failed to parse a schema.

I know TFoo is defined twice, and that's why I have the external binding to solve the conflict.

Obs. both schemas are fictitious, written to exemplify the problem, the real ones (many) are provided by a third party and I can't change them.

Can anyone tell me if this is some kind of xjc restriction (it's not listed here) or shouldn't work at all? Or maybe a bug?

Thanks in advance.

fscherrer
  • 218
  • 3
  • 8

2 Answers2

2

Having 2 different schema documents defining the same name space (and even worse - same element) is equivalent to having 2 different jars contain the same package and same class(es) in the package. This isn't a limitation of jaxb per se - it is a violation of what schema name spaces mean.

In short, you cannot process these schemas together.

The generator cannot create classes because it does not know what to reference. The failure occurs before your attempt to rename. It occurs when reading the schemas.

What you could do is process the schemas separately and change the java package names which are used. This avoids naming conflict in the java package space and basically treats the schema docs as completely separate entities with no references to each other. This can be done by defining the package name to use in the binding:

<jxb:bindings 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
  version="2.1">
    <jxb:bindings schemaLocation="a.xsd" node="/xs:schema">
      <jxb:schemaBindings>
        <jxb:package name="com.foo.a"></jxb:package>
      </jxb:schemaBindings>
    </jxb:bindings>
</jxb:bindings>
Brett Okken
  • 6,210
  • 1
  • 19
  • 25
  • the problem with separate compilation in my case is that both schemas include a third one, lets say **types.xsd**, which declares a lot of common types used across many other schemas, and, guess what, it uses the **same targetNamespace** too. So, if I do separately compilation, I end up with a dozen of duplicated classes in different pkgs. I've tried using **episode** extension, generating an episode file for **types.xsd**, but, (I think because of the same targetNamespace) when I try to use it (lets say `xjc -extension -b types.episode a.xsd`), nothing is generated. – fscherrer Jan 07 '15 at 15:25
  • This is simply a completely wrong of schema namespace. The only way to get this to work with jaxb is to generate a.xsd with types.xsd and force java name space 1 and have that be completely separate from generating b.xsd with types.xsd. – Brett Okken Jan 07 '15 at 18:23
  • What do you mean by "force java name space 1"? Sorry, didn't get that. I think I'm getting the problem solved with **episode**s, changing the generated _episode_ file (`` instead of `false`). There's another problem with it, but that's because of another part of the scenario I've not mentioned yet. I'm finishing my tests (with the real scenario) so I can update the question with the results I got. I'm accepting your answer, as it responds the question. – fscherrer Jan 09 '15 at 13:59
-1

I think you found a limitation of data binding. Try data projection instead (Disclosure: I'm affiliated with that project). Your schema b.xsd looks just like an extension to the a.xsd. You can create a projection interface suitable for b.xsd and use it with any documents that fit either a.xsd or b.xsd.

Cfx
  • 2,272
  • 2
  • 15
  • 21
  • Are you or are you not affiliated with this data projection library? – lexicore Jan 08 '15 at 08:40
  • Yes, I am. Does this change the usefulness of the answer in any direction? IMHO yes, because I know what I'm talking about. – Cfx Jan 08 '15 at 09:07
  • My point is that you [must disclose your affiliation](http://stackoverflow.com/help/behavior). – lexicore Jan 08 '15 at 09:21
  • I also think that your answer is off-topic (therefore the downvote). The OP is quite specific about using XJC and JAXB. Suggesting a completely different tool is not the right answer here, from my point of view. – lexicore Jan 08 '15 at 09:24
  • That is a valid point of view, as long as it is not affected by your affiliation with JAXB. (Metro?) (added my disclosure) – Cfx Jan 08 '15 at 09:29
  • None at all. I'm a tool author but completely indie. Thanks for the edit! Looks good now. – lexicore Jan 08 '15 at 09:30
  • Well, you did commit to the metro implmenentation. It was only correcting package naming, but you are affiliated with JAXB. However, your point stays valid: I was wrong not to disclosure. – Cfx Jan 08 '15 at 09:36
  • You're right, it would've been correct to say that I'm not affiliated with any of the vendors behind JAXB (Sun/Oracle/Eclispe/Apache). I do a lot for JAXB and always disclose authoriship of my tools on SO. My opinion that your answer to this question is off-topic is not influenced by this. – lexicore Jan 08 '15 at 10:14
  • I respect your opinion. I just have a different one because the problem is not solveble with data binding (as you stated correctly). So suggesting another tool that solves the problem is IMHO on topic. Suggesting the use of XStream or a pull parser would be ok, too. – Cfx Jan 08 '15 at 10:29