Managing JAXB-generated classes in a Maven project

Steve Perkins picture Steve Perkins · Aug 15, 2012 · Viewed 32k times · Source

I have a Maven-based project, in which I trying to add some JAXB classes automatically generated by the "jaxb2-maven-plugin" Maven plugin. However, my first cut has me in a circular dependency loop:

  • Because these JAXB classes aren't generated yet, my other sources which reference them have compilation errors.
  • Because those other sources have compilation errors, these JAXB classes don't get generated.

It seems like there are two obvious possibilities for solving this:

  1. Comment-out the broken references, so that the project builds and the JAXB classes are automatically generated. Then copy those generated sources from /target into /src/main/java, so that references to them won't cause compilation errors.
  2. Create an entirely separate project, consisting of nothing but the JAXB stuff. Include it as a dependency in my main project.

Am I missing something here? Option #1 seems flat-out ridiculous... that just can't be the manner in which people use JAXB. Option #2 seems more rational, but still rather inefficient and cumbersome. I really have to take on the overhead of an entirely separate project just to use JAXB?

Are there any more elegant approaches that developers use to reference JAXB-generated classes in the same project where the Maven plugin generates them?

UPDATE: By request, here is the relevant portion of my POM:

<build>
    <plugins>
        <plugin>
            <!-- configure the compiler to compile to Java 1.6 -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>       
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>1.4</version>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <!-- The name of your generated source package -->
                <packageName>com.mypackage</packageName> 
            </configuration>
        </plugin>
    </plugins>  
</build>

When I run mvn clean package, I DO see my JAXB sources being generated beneath the /target subdirectory. However, those generated sources are not being automatically added to the classpath for the compile phase.

POST-RESOLUTION UPDATE: It turns out that my compilation issues had more to do with the fact that I was running in Eclipse, and its Maven integration has some issues with "jaxb2-maven-plugin". See this StackOverflow question for more detail on that issue and its resolution.

Answer

Nicolas Mommaerts picture Nicolas Mommaerts · Aug 15, 2012

How did you configure your jaxb maven plugin? Normally it runs in the generate-sources lifecycle, which comes before the compile lifecycle. So your JAXB generated classes should already be there when your own code gets compiled, Maven puts them in target/generated-source and puts that folder on the classpath.

Edit: This is my code we use at work (and which works as expected):

<plugin>
            <groupId>com.sun.tools.xjc.maven2</groupId>
            <artifactId>maven-jaxb-plugin</artifactId>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <schemaDirectory>src/main/resources/<companyname>/xsd</schemaDirectory>
                <includeSchemas>
                    <includeSchema>retrieval.xsd</includeSchema>
                    <includeSchema>storage.xsd</includeSchema>
                </includeSchemas>
            </configuration>
        </plugin>

Apparently we use yet another jaxb plugin... (see also this thread: Difference of Maven JAXB plugins).