Rectangle 27 2

It is possible to achieve this for this simple case without using a 3rd Party plugin using the JAXB RI Vendor Extensions xjc:superInterface customization. It should be noted this approach will cause all generated classes to implement the interface.

<jxb:bindings version="1.0" 
  xmlns:jxb="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" 
  jxb:extensionBindingPrefixes="xjc">
    <jxb:bindings schemaLocation="adult.xsd" node="/xs:schema">
    <jxb:globalBindings>
        <xjc:superInterface name="com.example.model.Person"/>
    </jxb:globalBindings>
    </jxb:bindings>
</jxb:bindings>

You then just need to run xjc specifying the binding file and setting the -extension flag. Much quicker/simpler than bringing in JAXB2Basics!

I was initially sceptical that this would work as the documentation states:

The customization allows you to specify the fully qualified name of the Java interface that is to be used as the root interface of all the generated interfaces. This customization has no effect unless you are specifically generating interfaces with the globalBindings generateValueClass="false" switch.

But when I tried it out with a bindings similar to the one above (without specifying generateValueClass="false", and generating classes, not interfaces), it gave me the output I required - all my generated classes implemented the common interface.

this is not what the person asked (and usually, what most of the people want) as, as you said, this would make ALL the classes implement the same interface which is, most of the times, useless.

No, this is exactly what OP wanted; two schemas that generate two classes both implementing the same interface. It also happened to be a requirement I had in a real world project, so some times isn't useless at all. It is a fairly poorly documented area of JAXB, I don't think putting an example of its usage out there is a problem.

If JAXB generates more than two classes, adding a global binding section using <xjc:superInterface> will result in ALL of the classes implementing the Person interface, which doesn't seem to be reasonable for a domain consisting of more than two classes where not all the objects are persons.

Yes, you are right, all the generated classes will implement the interface, as I state in the second sentence of my answer. Sometimes this might be useful, is easy to achieve, and IS what OP asked. OK?

java - Generating a JAXB class that implements an interface - Stack Ov...

java xsd jaxb xjc jaxb2-basics
Rectangle 27 4

See this issue in XJC. In short, XJC for some reason does not allow custom/vendor customization elements in SCD bindings.inheritance:implements is such customization element.

So no, this does not work due a problem in XJC.

I personally bind via schemaLocation and XPath but use a "virtual" schema location URI and rewrite it via catalogs.

SCD would have been a much better choice (you're absolutely right here) but it just does not work.

Here's an example of binding which customizes some complex type:

<jaxb:bindings 
    schemaLocation="http://schemas.opengis.net/wps/2.0/wpsCommon.xsd" 
    node="/xs:schema">
    <jaxb:bindings node="xs:element[@name='Data']/xs:complexType">
        <wildcard:lax/>
    </jaxb:bindings>
</jaxb:bindings>

It is bound via schemaLocation and XPath. The schemaLocation is an existing URL, but in the build it is rewritten via catalog into the resource inside a Maven artifact:

REWRITE_SYSTEM "http://schemas.opengis.net" "maven:org.jvnet.ogc:ogc-schemas:jar::!/ogc"
http://schemas.opengis.net/wps/2.0/wpsCommon.xsd
ogc-schema.jar!/ogc/wps/2.0/wpsCommon.xsd
<binding>
                        <dependencyResource>
                            <groupId>${project.groupId}</groupId>
                            <artifactId>ows-v_2_0</artifactId>
                            <resource>ows-v_2_0.jsonix.xjb</resource>
                            <version>${project.version}</version>
                        </dependencyResource>
                    </binding>

So, in combination, it allows writing binding files once and reuse them across modules.

But this was all a huge pain to figure out. I did it for the ogc-schemas project which is now some 50 heavily interconnected schemas. I heavily suffer from XJC drawbacks and issues, but this is the best possible at the moment. I even thought about forking and patching XJC, but this is far of effort limits I can afford.

So I've ended up with a number of mindblogging workarounds which somehow do the job at the end of the day.

Thanks lexicore. What about combining scd and xjc:superInterface... Should that work? Any idea why this approach generates no error, but also does not seem to have any effect on the generated source?

... or is xjc:superInterface considered a custom/vendor customization just like inheritence:implements?

It is actually a vendor extension but its a "first class" vendor extension which is specifically known to XJC (see here) - unlike inheritance:implements. By the way, isn't xjc:superInterface for global bindings only? Would explain why it is ignored on the class.

I think the only thing which would work at the moment is binding to some "global" schemaLocation + XPath + catalogs.

All efforts to use this approach so far fail with this error: [ERROR] "file:/C:/dev/workspace/myapp/etc/form-schemas/common.xsd" is not a part of this compilation. Is this a mistake for "file:/C:/dev/workspace/myapp/etc/form-schemas/v0001/common.xsd"?

jaxb2 - JAXB generated classes of certain types implementing a custom ...

jaxb jaxb2 xjc scd
Rectangle 27 0

What can a plugin do?

A JAXB RI plugin participates in the code generation from a schema. It can define its own customizations that users can use to control it, it can access the code that the JAXB RI generates, and it can generate additional classes/methods/fields/annotations/comments.

A plugin can also choose to take over the XJC's code generation process completely. Only one plugin can do this at any given time, but this allows a plugin to generate radically different code from a schema.

But no, I don't think this is the right way to address the problem that you have.

Try to figure out the bindings or patch the schema.

java - XJC - is it extensible? - Stack Overflow

java jaxb xsd xjc
Rectangle 27 0

Well of course, I should have figured. As soon as I posted the question the solution presented itself.

According to JAXB "default binding rules", the binding compiler attempts to create a Java class for each Element and each named ComplexType. The collision was caused because cxml.payment was used for both names.

In this case, this simple class customization was all that was needed:

The lesson is to pay close attention to the line numbers in the xjc error messages. In this case, they were pointing me to line 2477 all the time.

jaxb - xjc: unable to honor class customization - Stack Overflow

jaxb xsd xjc
Rectangle 27 0

You can use an external binding file to rename one of the generated classes.

jaxb - XJC task in ANT script says "Use Class Customization" - Stack O...

ant jaxb
Rectangle 27 0

It is possible to achieve this for this simple case without using a 3rd Party plugin using the JAXB RI Vendor Extensions xjc:superInterface customization. It should be noted this approach will cause all generated classes to implement the interface.

You then just need to run xjc specifying the binding file and setting the -extension flag. Much quicker/simpler than bringing in JAXB2Basics!

I was initially sceptical that this would work as the documentation states:

The customization allows you to specify the fully qualified name of the Java interface that is to be used as the root interface of all the generated interfaces. This customization has no effect unless you are specifically generating interfaces with the globalBindings generateValueClass="false" switch.

But when I tried it out with a bindings similar to the one above (without specifying generateValueClass="false", and generating classes, not interfaces), it gave me the output I required - all my generated classes implemented the common interface.

this is not what the person asked (and usually, what most of the people want) as, as you said, this would make ALL the classes implement the same interface which is, most of the times, useless.

No, this is exactly what OP wanted; two schemas that generate two classes both implementing the same interface. It also happened to be a requirement I had in a real world project, so some times isn't useless at all. It is a fairly poorly documented area of JAXB, I don't think putting an example of its usage out there is a problem.

If JAXB generates more than two classes, adding a global binding section using <xjc:superInterface> will result in ALL of the classes implementing the Person interface, which doesn't seem to be reasonable for a domain consisting of more than two classes where not all the objects are persons.

Yes, you are right, all the generated classes will implement the interface, as I state in the second sentence of my answer. Sometimes this might be useful, is easy to achieve, and IS what OP asked. OK?

java - Generating a JAXB class that implements an interface - Stack Ov...

java xsd jaxb xjc jaxb2-basics
Rectangle 27 0

I ran into a similar issue only using maven-jaxb2-plugin. I ran the xjc command from the terminal and got the same issue. After adding this argument it resolved my issue. The command I used: xjc -wsdl -p com.package.wsdl -XautoNameResolution https://<YOUR_WSDL>. Thanks.

jaxb - XJC task in ANT script says "Use Class Customization" - Stack O...

ant jaxb