I suspect that there's no good answer to this, but hopefully I'm missing something. Let's say I have two separate XML schemas both with the same namespace, defining some duplicate complexTypes, and I want to generate Java classes for them with JAXB. As a very simplified example:
schema1.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified" targetNamespace="namespace1" xmlns="namespace1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="foo" type="xs:string"/>
</xs:schema>
and
schema2.xsd: (identical to the above)
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified" targetNamespace="namespace1" xmlns="namespace1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="foo" type="xs:string"/>
</xs:schema>
When I try to generate these with JAXB (Ant XJC task via gradle), I get the following, entirely reasonable error:
[ant:xjc] [ERROR] 'foo' is already defined
[ant:xjc] line 3 of file:/C:/dev/test/src/main/resources/schema2.xsd
[ant:xjc]
[ant:xjc] [ERROR] (related to above error) the first definition appears here
[ant:xjc] line 3 of file:/C:/dev/test/src/main/resources/schema1.xsd
As per the JAXB docs, I tried specifying the package in an external customisation file like this:
<jaxb:bindings schemaLocation="schema1.xsd">
<jaxb:schemaBindings>
<jaxb:package name="package1"/>
</jaxb:schemaBindings>
</jaxb:bindings>
<jaxb:bindings schemaLocation="schema2.xsd">
<jaxb:schemaBindings>
<jaxb:package name="package2"/>
</jaxb:schemaBindings>
</jaxb:bindings>
but that doesn't work - I then realised that the same docs linked above say:
Note that this customization is per namespace. That is, even if your schema is split into multiple schema documents, you cannot put them into different packages if they are all in the same namespace.
So, I'm guessing that's never going to work.
Is there any sensible approach to this? I suspect the correct answer is that the schemas should be in different namespaces, as that would resolve the issue, and probably make more logical sense, but I don't have any control over the schemas - they are provided by a 3rd party. I've asked if it's possible to change them, but I suspect the answer is no.
The only other option I can see is to generate the Java classes twice, first for schema1.xsd, and then separately for schema2.xsd, each time with their own customisation file specifying a different package, but that feels like a very clumsy solution. Is there any more sensible option that I'm missing?
You can't. Packages are generated based on namespaces. Same namespace - same package.
You have to do several executions in this case. Also mind to use different output generation directories (like target/generated-sources/xjc1
, target/generated-sources/xjc2
) otherwise "compile only if anything was changed" won't work correctly.