How can I tell jaxb / Maven to generate multiple schema packages?
Solution 1
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.
Solution 2
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.
Solution 3
you should change that to define the plugin only once and do twice execution areas...like the following...and the generateDirectory should be set (based on the docs)..
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.1</version>
<executions>
<execution>
<id>firstrun</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generateDirectory>target/gen1</generateDirectory>
<schemaDirectory>src/main/resources/dir1</schemaDirectory>
<schemaIncludes>
<include>schema1.xsd</include>
</schemaIncludes>
<generatePackage>schema1.package</generatePackage>
</configuration>
</execution>
<execution>
<id>secondrun</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generateDirectory>target/gen2</generateDirectory>
<schemaDirectory>src/main/resources/dir2</schemaDirectory>
<schemaIncludes>
<include>schema2.xsd</include>
</schemaIncludes>
<generatePackage>schema2.package</generatePackage>
</configuration>
</execution>
</executions>
</plugin>
It seemed to me that you are fighting against single artifact rule of maven...may be you should think about this.
Solution 4
This can also be achieved by specifying stale file name for schemas and not clearing output directory. The default out put directory is automatically included in classpath which is little convenient. If we specify different output directory one has to take care of classpath to use this code in IDE. For example -
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<quiet>true</quiet>
<verbose>false</verbose>
<clearOutputDir>false</clearOutputDir>
<readOnly>true</readOnly>
<arguments>-mark-generated</arguments>
</configuration>
<executions>
<execution>
<id>reportingSchema</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/schema/r17/schemaReporting</schemaDirectory>
<schemaIncludes>
<include>OCISchemaReporting.xsd</include>
</schemaIncludes>
<packageName>com.broadsoft.oci.r17.reporting</packageName>
<staleFile>${build.directory}/generated-sources/.jaxb-staleFlag-reporting</staleFile>
</configuration>
</execution>
<execution>
<id>schemaAS</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/schema/r17/schemaAS</schemaDirectory>
<schemaIncludes>
<include>OCISchemaAS.xsd</include>
</schemaIncludes>
<packageName>com.broadsoft.oci.r17.as</packageName>
<staleFile>${build.directory}/generated-sources/.jaxb-staleFlag-as</staleFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Source:Generating Code with JAXB Plugin
Solution 5
i have solved with:
<removeOldOutput>false</removeOldOutput>
<clearOutputDir>false</clearOutputDir>
<forceRegenerate>true</forceRegenerate>
add this to each configuration ;)
M.R.
Updated on March 08, 2020Comments
-
M.R. about 4 years
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.
-
Devanshu Mevada almost 14 yearsThe one artifact per module rule is true but... the OP is not generating two artifacts.
-
Newtopian almost 14 yearsthanks, I actually had the same problem yesterday but momentarily gave op on it. Your solution works almost perfectly, my only issue now is that I cannot get Eclipse to compile without error. All is good on the command line though. My current workaround is that I declare these folders in target as source folders and all is good.. though I'm not certain I like it much, I'd rather create a jar with the generated code and just use it directly
-
M.R. almost 14 yearsThe eclipse plugin m2eclipse does update the build path. After generating the beans with mvc clean assembly:assembly I just run [right click on project] > [Maven] > [Update Project Configuration] and it updates the build path.
-
Devanshu Mevada almost 14 years@Newtopian See @M.R.'s comment, m2eclipse will do that for you if you follow the convention I mentioned.
-
Newtopian almost 14 yearshmm ok then, turns out to do the same thing I did manually, only now it takes just one or two clicks. Still strange to see target in the source folders but now it's almost free to do so I'll keep it :-)
-
Admin over 12 yearsYou could also add it only to the
<executions>
tag. That's sufficient.<removeOldOutput>
is set to false by default. But I can't find<clearOutputDir>
at static.highsource.org/mjiip/maven-jaxb2-plugin/… -
santiagozky about 12 yearswhat if the schemaDirectory is the same for all? I have many xsd's and wsdl that should be mapped to different packages. in my case all the packages end up having all the classes (all classes in all packages)
-
Kev over 11 yearsWhilst trivial the edit to provide a syntax highlight hint does improve the legibility of the post
-
xmedeko over 11 yearsOK, thanks for the explanation. I have not get that the edit added syntax highlighting.
-
Rakesh about 11 yearsHad to add staleFile for both the configurations <staleFile>${project.build.directory}/jaxb2/.xjcStaleFlag_1</staleFile>
-
Ben Thurley over 10 yearsThis is the best answer for me as I wouldn't want to keep changing the pom each time a new schema is added.
-
dario nascimento almost 9 yearsAny way to have a single "execution" tag for all files instead of specifying one "execution" per schema?
-
MilacH almost 7 yearsFor me the real solution, cause you can generate everythong in same folder
-
Denis Stephanov over 6 yearsI know it is old question but I hope something answer me. I use that code and it works. But when I want set up same same package it always generate only one schema. For example in first execution I set com.myproject.answer and in second execution com.myproject.request .. and after source generating I have only *answer package and request is missing ... any idea how to fix it? Generate directory I set also same.
-
MattWeiler about 5 yearsThank you, I had this same issue and this worked perfectly for me :)
-
TurnipEntropy almost 4 yearsThe one issue here is if book and person are in the same target namespace in the xsd. Let's say instead they had book, journal, newspaper, etc. all of which included publishable.xsd. They'd have to be in the same namespace as publishable, and thus each other, and now this breaks because you can only have one schemaBindings per namespace. I agree it's ideal, and I wish it worked for the example above, but JAXB just isn't flexible enough.
-
Ruwanka Madhushan almost 4 years
<clearOutputDir>false</clearOutputDir>
was enough for me in my case. -
MrSmith42 over 3 yearsSadly this does not work when I use the same `generateDirectoryor more than one block.