-1

I am trying to generate Java code for two XSDs (let's say request.xsd and response.xsd) using JAXB

Request.xsd includes A.xsd which defines a complex type "FOO"

Response.xsd includes B.xsd which defines a complex type "FOO" too (different type with the same name).

Initially, I thought of adding to both XSDs something like in order to fix the name clash.

<xsd:annotation>
   <xsd:appinfo>
      <jaxb:class name="AFOO"/> (and BFOO)
   </xsd:appinfo>
</xsd:annotation>

However, I still get the error that "FOO" is already defined. If I try to generate code only for request.xsd or only for response.xsd the code is generated correctly.

My initial pom.xml looks like:

   <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <version>0.8.2</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <debug>true</debug>
                <schemaDirectory>src/main/resources/xsds</schemaDirectory> 
                <generateDirectory>src/main/generated</generateDirectory>
                <generatePackage>com.mycompany.generated</generatePackage> 
                <extension>true</extension>
                <markGenerated>true</markGenerated>
                <args>
                    <arg>-camelcase-always</arg>
                    <arg>-XtoString</arg>
                    <arg>-Xequals</arg>
                    <arg>-XhashCode</arg>
                    <arg>-Xsetters</arg>
                </args>
                <plugins>
                    <plugin>
                        <groupId>org.jvnet.jaxb2_commons</groupId>
                        <artifactId>jaxb2-basics</artifactId>
                        <version>0.6.4</version>
                    </plugin>
                    <plugin>
                        <groupId>org.andromda.thirdparty.jaxb2_commons</groupId>
                        <artifactId>camelcase-always</artifactId>
                        <version>1.0</version>
                    </plugin>
                </plugins>
            </configuration>
        </plugin>

Eventually, I managed to get it to work using different executions for request and response.

<executions>
                    <execution>
                        <id>Output</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                        <configuration>
                            <forceRegenerate>true</forceRegenerate>
                            <debug>true</debug>
                            <schemaDirectory>src/main/resources/xsds</schemaDirectory> 
                            <generateDirectory>src/main/generated</generateDirectory>
                            <schemaIncludes>
                                <include>
                            response.xsd
                                </include>
                            </schemaIncludes> 
                            <generatePackage>com.mycompany.generated.reply</generatePackage>
                            ....
                        </configuration>
                    </execution>

                    <execution>
                        <id>Input</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>

                        <configuration>
                            <forceRegenerate>true</forceRegenerate>
                            <debug>true</debug>
                            <schemaDirectory>src/main/resources/xsds</schemaDirectory> 
                            <generateDirectory>src/main/generated</generateDirectory>
                            <schemaIncludes>
                                <include>
                            request.xsd
                                </include>
                            </schemaIncludes> 
                            <generatePackage>com.mycopnay.generated.query</generatePackage>
                            ...
                        </configuration>
                    </execution>
                </executions>

In this way, it works. However I have the following questions:

  • Is there any better way to make it work without modifying the xsd? A lot of classes are shared between request and response are generated twice (under different java packages). Is there any way to reuse them?
  • Why overriding the class name (my initial solution) does not work?
alampada
  • 2,329
  • 1
  • 23
  • 18

2 Answers2

3

Do A.xsd and B.xsd have different namespaces?

No, they don't.

This is why. You can't customize it then because the collision is not in Java code but in schemas. You have distinct schema components under the same name, you can't compile it as one.

  • Either compile in two executions
  • Or make them one (as David Rabinowitz advised)
  • Or put them in different namespaces

A few hints:

  • Your design seems to go in the direction of chameleon schema design. By all means avoid it.
  • When compiling with multiple executions, specify different generateDirectory per execution, see this discussion.

Disclaimer: I am the author of the maven-jaxb2-plugin.

Community
  • 1
  • 1
lexicore
  • 42,748
  • 17
  • 132
  • 221
  • Thanks for the reply. I am currently working with legacy XSDs. I am experimenting with using jaxb, because I think it's a step towards the right direction instead of writing containers manually, but I'd like to keep modifications to the XSDs to a minimum. – alampada Nov 24 '14 at 15:26
  • At now, is there some new option of the plugin in order to automate the creation of different directories (or packages) or to bypass "already defined" types? @lexicore – s1moner3d Oct 25 '18 at 14:21
  • @s1moner3d Not sure what you mean by "automate". "Already defined types" is a problem in schemas. The plugin can't fix it for you. – lexicore Oct 26 '18 at 08:10
  • @lexicore reading logs, the plugin seems searching xsd starting from workspace directory, even if I put prefix the source path with _${project.basedir}_ How to make it treat it as absolute path? – s1moner3d Oct 26 '18 at 15:53
2

Is it an XSD you control? If so, define a common.xsd and import is from both XSDs. In this way you will define FOO only once.

David Rabinowitz
  • 29,904
  • 14
  • 93
  • 125