I have two projects:
A /src/main/resources/schema.xsd pom.xml
B /src/main/gen pom.xml
I want in B project generate classes from XSD, that exists in A Project
In pom.xml of B project 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 xsd file is not found in classpath:
Failed to execute goal org.codehaus.mojo:jaxb2-maven-plugin:1.5:xjc (xjc) on project B: No schemas have been found
How can I use xsd from another project?
My maven-jaxb2-plugin
supports separate schema compilation.
How to do this:
a
as episode.a.xsd
is imported into b.xsd
, you have to make this schema available to JAXB when compiling b
:
a.xsd
from the artifact a
using Maven dependency plugin, for instance.a.xsd
into the artifact a
See this test project for example.
The project a
is totally unspectacular. Just compiles the schema a.xsd
.
The project b
is more interesting. Let's take 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 says use the artifact a
as episode. So when JAXB/XJC meets classes compiled in a
, it will reuse them instead of generating new ones.
By the way, you can use the useDependenciesAsEpisodes
instead of configuring individual episodes. In this case all the dependencies will be treated as episodes which is very convenient (less configuration).
The configuration also says to use the catalog file:
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 starting with http://www.ab.org
to start with maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!
instead. The latter will be processed by the maven-jaxb2-plugin
and finally resolved to the resource in a
.
Let's take a closer look. The schema b.xsd
imports 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
which will be resolved to the a.xsd
inside the JAR of the project a
. So, finally, JAXB/XJC will be able to read this schema from the a
's JAR artifact.
You can also use PUBLIC
instead of REWRITE_SYSTEM
to reference a.xsd
per namespace URI instead of 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's a bug in JAXB/XJC this does not work if you have schemaLocation
in your xs:import
.
This would work at the moment:
<xsd:import namespace="urn:a"/>
This won't work at the moment:
<xsd:import namespace="urn:a" schemaLocation="a.xsd"/>
I've sent Oracle a pull request which fixes that but it's not applied yet.
The explanation above applies to the maven-jaxb2-plugin
and works in versions 0.10.0 and higher.
Your original question is about jaxb2-maven-plugin
from Codehaus which is a different Maven plugin. This plugin does not have all the features I've described above, but at least episodes should work via arguments. Catalogs must also work, but I believe, jaxb2-maven-plugin
does not support resolving schemas in Maven artifacts. You can use the maven-dependency-plugin
to extract a.xsd
from artifact a
instead.
SO disclaimer: I am the author of the maven-jaxb2-plugin
.
Note for reviewers: it is NOT my intention here to push/advertise my plugin, I just want to provide a solution to the asked question. And it appears that my project offers the best/most elegant and full solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With