Example:
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources/dir1</schemaDirectory>
<schemaIncludes>
<include>schema1.xsd</include>
</schemaIncludes>
<generatePackage>schema1.package</generatePackage>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources/dir2</schemaDirectory>
<schemaIncludes>
<include>schema2.xsd</include>
</schemaIncludes>
<generatePackage>schema2.package</generatePackage>
</configuration>
</plugin>
</plugins>
What happened: Maven executes the the first plugin. Then deletes the target folder and creates the second package, which then is visible.
I tried to set target/somedir1 for the first configuration and target/somedir2 for the second configuration. But the behavior does not not change? Any ideas? I do not want to generate the packages directly in the src/main/java folder, because these packages are genereated and should not be mixed with manual created classes.
The solution is to add multiple executions for the maven-jaxb2-plugin plugin. Each execution is bound to the generate-resources phase of the Maven build process. Now, each time the project is build, the executions kick in and the JAXB classes are generated. Execution “One” will generate the JAXB classed for schema-1.
Just build the maven project using mvn clean install and you will see java classes generated in target/generated-sources/jaxb directory.
This plugin uses the Java API for XML Binding (JAXB), version 2+, to generate Java classes from XML Schemas (and optionally binding files) and to create XML Schemas from annotated Java classes.
I had to specify different generateDirectory
(without this, the plugin was considering that files were up to date and wasn't generating anything during the second execution). And I recommend to follow the target/generated-sources/<tool>
convention for generated sources so that they will be imported in your favorite IDE automatically. I also recommend to declare several execution
instead of declaring the plugin twice (and to move the configuration
inside each execution
element):
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<id>schema1-generate</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/dir1</schemaDirectory>
<schemaIncludes>
<include>shiporder.xsd</include>
</schemaIncludes>
<generatePackage>com.stackoverflow.package1</generatePackage>
<generateDirectory>${project.build.directory}/generated-sources/xjc1</generateDirectory>
</configuration>
</execution>
<execution>
<id>schema2-generate</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/dir2</schemaDirectory>
<schemaIncludes>
<include>books.xsd</include>
</schemaIncludes>
<generatePackage>com.stackoverflow.package2</generatePackage>
<generateDirectory>${project.build.directory}/generated-sources/xjc2</generateDirectory>
</configuration>
</execution>
</executions>
</plugin>
With this setup, I get the following result after a mvn clean compile
$ tree target/ target/ ├── classes │ ├── com │ │ └── stackoverflow │ │ ├── App.class │ │ ├── package1 │ │ │ ├── ObjectFactory.class │ │ │ ├── Shiporder.class │ │ │ ├── Shiporder$Item.class │ │ │ └── Shiporder$Shipto.class │ │ └── package2 │ │ ├── BookForm.class │ │ ├── BooksForm.class │ │ ├── ObjectFactory.class │ │ └── package-info.class │ ├── dir1 │ │ └── shiporder.xsd │ └── dir2 │ └── books.xsd └── generated-sources ├── xjc │ └── META-INF │ └── sun-jaxb.episode ├── xjc1 │ └── com │ └── stackoverflow │ └── package1 │ ├── ObjectFactory.java │ └── Shiporder.java └── xjc2 └── com └── stackoverflow └── package2 ├── BookForm.java ├── BooksForm.java ├── ObjectFactory.java └── package-info.java
Which seems to be the expected result.
You can use also JAXB bindings to specify different package for each schema, e.g.
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0" schemaLocation="book.xsd">
<jaxb:globalBindings>
<xjc:serializable uid="1" />
</jaxb:globalBindings>
<jaxb:schemaBindings>
<jaxb:package name="com.stackoverflow.book" />
</jaxb:schemaBindings>
</jaxb:bindings>
Then just use the new maven-jaxb2-plugin 0.8.0 <schemas>
and <bindings>
elements in the pom.xml
. Or specify the top most directory in <schemaDirectory>
and <bindingDirectory>
and by <include>
your schemas and bindings:
<schemaDirectory>src/main/resources/xsd</schemaDirectory>
<schemaIncludes>
<include>book/*.xsd</include>
<include>person/*.xsd</include>
</schemaIncludes>
<bindingDirectory>src/main/resources</bindingDirectory>
<bindingIncludes>
<include>book/*.xjb</include>
<include>person/*.xjb</include>
</bindingIncludes>
I think this is more convenient solution, because when you add a new XSD you do not need to change Maven pom.xml
, just add a new XJB binding file to the same directory.
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