How can I generate classes from external XSD file using JAXB XJC

I have two projects:

a /src/main/resources/schema.xsd pom.xml

In / src / main / gene pom.xml

I want project B to generate classes from XSD that exists in Project

In the pom.xml of project B, I have:

<dependencies>
    <dependency>
        <groupId>test</groupId>
        <artifactId>A</artifactId>
        <version>${project.version}</version>
    </dependency>
</dependencies>
<build>
    <plugins>
       <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>jaxb2-maven-plugin</artifactId>
        <executions>
            <execution>
                <id>xjc</id>
                <goals>
                    <goal>xjc</goal>
                </goals>
            </execution>
            </executions>
            <configuration>
                <schemaDirectory>src/main/resources</schemaDirectory>
                <outputDirectory>src/main/gen</outputDirectory>
            </configuration>
        </plugin>
    </plugins>

</build>

      

But the xsd file was not found in the classpath:

Failed to execute target org.codehaus.mojo: jaxb2-maven-plugin: 1.5: xjc (xjc) in project B: No schemas found

How can I use xsd from another project?

+3


source to share


3 answers


The problem with this configuration is what the name / path is <schemaDirectory>

expecting File

. The point File

is that it looks for files in the file system, looking from the current working directory. In this case, the root of the project. But the resource from project A is not in src/main/resources

project B. It is the classpath resource from which (when built in maven) src/main/resources

no longer exists.

I've never tried using the jaxb2-maven-plugin , so I'm not sure if this is possible.

But with maven-jaxb2-plugin it allows Compiling schema from Maven artifact . You could something like



<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <version>0.9.0</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <schemas>
            <schema>
                <dependencyResource>
                    <groupId>projecta.groupid</groupId>
                    <artifactId>project-a</artifactId>
                    <version>${project.version}</version>
                    <resource>/schema.xsd</resource>
                </dependencyResource>
            </schema>
        </schemas>
        <generateDirectory>src/main/gen/</generateDirectory>
        <generatePackage>mypackage</generatePackage> 
    </configuration>
</plugin>

      

In this case the resource (schema.xsd) is in src/main/resources

project A. The plugin generates class files in a package mypackage

and sendssrc/main/gen

+4


source


My maven-jaxb2-plugin

supports separate compilation of the schema .

How to do it:

  • Add your artifact a

    as an episode.
  • If a.xsd

    imported into b.xsd

    , you must make this schema available to JAXB at compile time b

    :
    • One way to do this is to extract a.xsd

      from the artifact a

      using the Maven dependency plugin for example.
    • Another way would be to use a catalog file to rewrite the location a.xsd

      into an artifacta

See this test project .

The project a

is completely invisible. It just compiles the schema a.xsd

.

The project is more interesting b

. Let's get a look.

pom.xml

:

        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <configuration>
                <catalog>src/main/resources/catalog.cat</catalog>
                <episodes>
                    <episode>
                        <groupId>org.jvnet.jaxb2.maven2</groupId>
                        <artifactId>maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a</artifactId>
                    </episode>
                </episodes>
            </configuration>
        </plugin>

      

The configuration uses the artifact a

as an episode. So when JAXB / XJC comes across classes compiled to a

, it will reuse them instead of generating new ones.

By the way, you can use useDependenciesAsEpisodes

instead of setting individual episodes. In this case, all dependencies will be treated as episodes, which are very handy (less configuration).

The config also says that the directory file is :

REWRITE_SYSTEM "http://www.ab.org" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!"

      

This instructs JAXB / XJC to rewrite all schema urls from http://www.ab.org

to start with maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!

. The latter will be processed maven-jaxb2-plugin

and finally the resource in the a

.

Let's go closer. Driving import statement :b.xsd

http://www.ab.org/a.xsd



<import namespace="urn:a" schemaLocation="http://www.ab.org/a.xsd"/>

      

This will be rewritten to maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!/a.xsd

be allowed a.xsd

inside the project JAR a

. So finally JAXB / XJC will be able to read this schema from the a

JAR artifact .

You can also use PUBLIC

instead REWRITE_SYSTEM

to refer a.xsd

to the namespace URI instead of the schema location (which is logically better):

PUBLIC "urn:a" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!/a.xsd"

      

However there is a bug in JAXB / XJC this doesn't work if you have schemaLocation

a xs:import

.

This will work for the moment:

<xsd:import namespace="urn:a"/>

      

This won't work at the moment:

<xsd:import namespace="urn:a" schemaLocation="a.xsd"/>

      

I have submitted an Oracle pull request that fixes this, but it is not being applied yet.

The explanation above applies to maven-jaxb2-plugin

and works in versions 0.10.0 and higher.

Your original question is jaxb2-maven-plugin

from Codehaus, which is another Maven plugin. This plugin does not have all the features described above, but at least episodes should work through arguments . Directories should work as well, but I believe jaxb2-maven-plugin

doesn't support schema resolution in Maven artifacts. You can use maven-dependency-plugin

to extract a.xsd

from artifact a

.

SO Disclaimer: I am the author maven-jaxb2-plugin

.

Note to reviewers: it is not my intention here to push / advertise my plugin, I just want to provide a solution to the question asked. And it looks like my project offers the best / most elegant and complete solution.

+6


source


We can also use as below in pom.xml file

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>1.5</version>
            <executions>
                <execution>
                    <id>id1</id>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>src/main/java</outputDirectory>
                        <clearOutputDir>false</clearOutputDir>
                        <packageName>com.subu.xsd.model</packageName>
                        <schemaDirectory>src/main/java/schemadir</schemaDirectory>
                        <schemaFiles>XYZ.xsd</schemaFiles>
                    </configuration>
                </execution>
            </executions>
        </plugin>

      

0


source







All Articles