Generating sources by running a project's java class in Maven
You can execute the maven-compile-plugin in the generate-sources phase. Just add another execution before the existing execution and configure it so that it just picks up the sources for the generator.
Or split the project in two: build the generator with a separate POM and include the generator library as a dependency to the POM that's generating the sources.
Personally I would split the project. Keeps the build files cleaner and easier to maintain.
I didn't want to have 2 different projects, so I tried to setup Maven for adding the generated compiled code to the final jar package.
This is the working solution I've used:
- In
process-classes
phase (executed just after thecompile
phase):exec-maven-plugin
for executing a main class able to generate my source files intarget/generated-sources/java
folder (in my specific case I used the Roaster library for source code generation);build-helper-maven-plugin
for adding the generated sources in the correct location
- In
prepare-package
phase:maven-compiler-plugin
, in order to detect the changes and recompile the modulemaven-jar-plugin
for producing the jar package
This is my pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>com.example.MyClassWriter</mainClass>
<arguments>
<argument>${project.basedir}</argument>
<argument>${project.build.directory}</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<phase>prepare-package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
In order to do this in one project, there are 3 steps:
Compile generator code
We can do it in
generate-sources
phase, usingmaven-compiler-plugin
. You can also exclude other source files.Run generator to generate code
We can do it in
process-sources
phase, usingexec-maven-plugin
.Compile project
Below is the key part of pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<id>compile-generator</id>
<phase>generate-sources</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<includes>
<include>source/file/of/generator/*.java</include>
</includes>
<excludes>
<exclude>other/source/files/*.java</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>generate-codes</id>
<goals>
<goal>java</goal>
</goals>
<phase>process-sources</phase>
<configuration>
<mainClass>your.main.class.of.generator</mainClass>
</configuration>
</execution>
</executions>
</plugin>