Java source code generation and Maven

Imagine you are working on a project where you use some Java code generated from a tool.
For the moment, you generate the code and integrate it yourself to the project:

Original Maven project structure

How would you automate this code generation step in your Maven build?

1. Create a separate Maven project where you will package the result of the code generation.

We package the result of the code generation in a separate JAR. Therefore, we need a different project structure.

New Maven project structure

We create a parent project with two child Maven modules. One with the original code, the other where the generated code will be located.
The parent POM looks like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>com.clempinch</groupId>
		<artifactId>myproject</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<groupId>com.clempinch</groupId>
	<artifactId>sample</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>com.clempinch</groupId>
			<artifactId>generated-code</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>

</project>

2. Automate the code generation in Maven.

If a Maven plugin is not already provided to generate the source code, then you can probably use the Exec Maven plugin to do the job.

Here is the pom.xml of the code generation project (we assume you generate the code via a Java application – hence the use the exec:java plugin).

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.clempinch</groupId>
    <artifactId>myproject</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <groupId>com.clempinch</groupId>
  <artifactId>generated-code</artifactId>

  <dependencies>
    <!-- For generating source code -->
    <dependency>
      <groupId>com.clempinch</groupId>
      <artifactId>some-generation-jar</artifactId>
      <version>1.0.0</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>generateCode</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>java</goal>
            </goals>
            <configuration>
              <mainClass>com.clempinch.generation.MainClass</mainClass>
              <classpathScope>runtime</classpathScope>
              <sourceRoot>${project.build.directory}/generated-sources/main/java</sourceRoot>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>addtoSourceFolder</id>
            <goals>
              <goal>add-source</goal>
            </goals>
            <phase>process-sources</phase>
            <configuration>
              <sources>
                <source>${project.build.directory}/generated-sources/generation_place</source>
              </sources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

3. Add the dependency to your initial project.

The pom.xml of the initial project needs to add a dependency to the generated-code JAR package:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>	
	<parent>
		<groupId>com.clempinch</groupId>
		<artifactId>myproject</artifactId>
		<version>0.0.1-SNAPSHOT</version>
        </parent>
	<groupId>com.clempinch</groupId>
	<artifactId>sample</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>com.clempinch</groupId>
			<artifactId>generated-code</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
</project>

4. Build the project from the parent POM.

mvn clean install

Now everything should be done automatically: the code generation and the build of the project.