I am trying to find a way to review the files generated by running mvn install, my task basically is, review if the total characters in the name are correct, if at least one file name is not complying, I should make certain task.
Is this possible in a pom with maven?
you can use dependency:analyze for that,
[https://maven.apache.org/plugins/maven-dependency-plugin/analyze-mojo.html]
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>analyze</id> <!-- notice the execution id "analyze" -->
<goals>
<goal>analyze</goal>
</goals>
<configuration>
<ignoreNonCompile>true</ignoreNonCompile>
</configuration>
</execution>
</executions>
Related
I need to generate a file with the dependency-jars of project.
This can be done with the dependeny plugin.
See below the snippet from the pom:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<execution>
<id>list-dependencies</id>
<phase>package</phase>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<prefix></prefix>
<outputFile>target/modules-list.txt</outputFile>
<pathSeparator>\n</pathSeparator>
</configuration>
</execution>
</executions>
</plugin>
However, since I need each jar on a separate line, I tried to specify the pathSeparator to be a newline character. However, this does not work. I didn't find a useful way to specify a newline character in the pom.
Any ideas on how this can be achieved?
Maven is trimming your <pathSeparator> value, which results in an empty value because the line separator is considered whitespace. Then, since there is no value, Maven falls back to using the default. I don't see any easy way to work around this behavior.
There are a few other options. You could consider using the dependency:list goal:
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>list-dependencies</id>
<phase>package</phase>
<goals>
<goal>list</goal>
</goals>
<configuration>
<outputFile>target/modules-list.txt</outputFile>
</configuration>
</execution>
</executions>
</plugin>
target/modules-list.txt
The following files have been resolved:
org.slf4j:slf4j-log4j12:jar:1.7.10:compile
org.hamcrest:hamcrest-core:jar:1.3:test
junit:junit:jar:4.11:test
log4j:log4j:jar:1.2.17:compile
org.slf4j:slf4j-api:jar:1.7.10:compile
javax.ws.rs:jsr311-api:jar:1.1.1:compile
com.sun.jersey:jersey-server:jar:1.19:compile
com.sun.jersey:jersey-core:jar:1.19:compile
This is the Maven artifact IDs instead of the jar file names. Arguably, this is actually more valuable, because the output won't change across different machines running the build. (The jar files would use absolute paths, which might be different across different machines.)
If it really has to be jar file names instead of Maven artifact IDs, then you could cobble something together by injecting a non-whitespace character into the <pathSeparator> value, so that even after Maven trims the value, there is something remaining to override the default path separator.
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>list-dependencies</id>
<phase>package</phase>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputFile>target/modules-list.txt</outputFile>
<pathSeparator>_${line.separator}</pathSeparator>
</configuration>
</execution>
</executions>
</plugin>
target/modules-list.txt
/Users/naurc001/.m2/repository/com/sun/jersey/jersey-core/1.19/jersey-core-1.19.jar_
/Users/naurc001/.m2/repository/javax/ws/rs/jsr311-api/1.1.1/jsr311-api-1.1.1.jar_
/Users/naurc001/.m2/repository/com/sun/jersey/jersey-server/1.19/jersey-server-1.19.jar_
/Users/naurc001/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar_
/Users/naurc001/.m2/repository/org/slf4j/slf4j-api/1.7.10/slf4j-api-1.7.10.jar_
/Users/naurc001/.m2/repository/org/slf4j/slf4j-log4j12/1.7.10/slf4j-log4j12-1.7.10.jar_
/Users/naurc001/.m2/repository/junit/junit/4.11/junit-4.11.jar_
/Users/naurc001/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar
Unfortunately, that leaves you with the ugly underscores at the end. If you want to clean those up, then you'd need another build step to clean those up. One approach would be to generate this file in the generate-resources phase, and then use maven-resources-plugin to do a token substitution during the process-resources phase.
Finally, if you just need this information for documentation purposes, consider using the site documentation provided by the maven-project-info-reports-plugin.
In XML you can specific a newline character using the following escape sequence -
Unfortunately, as you already mentioned, the <pathSeparator> value is trimmed of all leading and trailing whitespace, effectively resulting in an empty string value causing the plugin to use its default value.
However, you can use an Ant task in the same phase to replace the path separator. For example.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>list-dependencies</id>
<phase>package</phase>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<prefix></prefix>
<outputFile>target/modules-list.txt</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<!-- Replace path separator -->
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>package</phase>
<configuration>
<target>
<replace file ="target/modules-list.txt" token="${path.separator}" value="${line.separator}" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Note that the <pathSeparator> is no longer defined in your dependency configuration.
For my small Java/Maven application , I am using JaCoCo in my POM.xml as under:
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.6.201602180812</version>
<configuration>
<destFile>${basedir}/target/coverage-reports/jacoco.exec</destFile>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
As long as I dont use the <destFile> parameter, the default reports in target/site/jacoco folder are correctly generated in XML, CSV and HTML format. But when I use the <destFile> element in order to change the default folder where the reports are generated, only the jacoco.exec file is generated and nothing else. How can I change the report folder as well as get the reports in csv, xml and html formats?
With the destFile parameter, you changed the location where the prepare-agent goal will write the execution data file. By default, this is ${project.build.directory}/jacoco.exec, meaning (still by default) target/jacoco.exec. However, the report goal expects the path to the execution file to be passed in the dataFile parameter, which, of course, defaults to ${project.build.directory}/jacoco.exec, so that they are in sync. Therefore, if you want to change the path to this execution file, you need to match those two parameters. In order not to duplicate the path, you can use a Maven property to do that:
<properties>
<jacoco.execution.file>${project.build.directory}/coverage-reports/jacoco.exec</jacoco.execution.file>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.7.201606060606</version>
<configuration>
<destFile>${jacoco.execution.file}</destFile>
<dataFile>${jacoco.execution.file}</dataFile>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note that this will not change the output directory of the JaCoCo reports; this just changes the path to the execute file. For that, you can use the outputDirectory parameter:
Output directory for the reports. Note that this parameter is only relevant if the goal is run from the command line or from the default build lifecycle. If the goal is run indirectly as part of a site generation, the output directory configured in the Maven Site Plugin is used instead.
and have the following configuration element added:
<configuration>
<!-- rest of your JaCoCo configuration -->
<outputDirectory>${project.build.directory}/coverage-reports/jacoco</outputDirectory>
</configuration>
This will make sure all of the HTML, XML, and CSV reports are generated under target/coverage-reports/jacoco. Take note that this configuration will not be used as part of the Maven Site generation when launching mvn site. During site generation, you'll need to configure the outputDirectory of the maven-site-plugin instead.
I am having problems building a maven project. I have a requirement to produce deterministic jar files, which must be binary-consistent across different builds and versions, in case there are no source code changes in between these builds. For the purpose, I have used this article for guidance.
I have successfully managed to build my jars and they are consistent up to my requirements. Here is my configuration:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>step-1-remove-timestamp</id>
<phase>prepare-package</phase>
<configuration>
<target>
<touch datetime="01/01/2015 00:10:00 am">
<fileset dir="target/classes"/>
<fileset dir="src"/>
</touch>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>step-3-rename-assembly</id>
<phase>package</phase>
<configuration>
<target>
<copy file="${project.build.directory}/${project.build.finalName}-deterministic.zip"
tofile="${project.build.directory}/${project.build.finalName}.jar"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/zip.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>step-2-make-assembly</id>
<phase>prepare-package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
In the above code I build and package the jar as a zip, then copy the zip over the expected jar artifact.
The problem with the above, is that maven still executes the maven-jar-plugin, so the manually assembled jar is overwritten by the one of the maven-jar-plugin. I do not want to use this jar, since it is not consistent with my requirements.
So, I have disabled the maven-jar-plugin execution, by explicitly setting it to run for an invalid phase, like below: (saw that from other posts here)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-jar</id>
<phase>never</phase>
<configuration>
<finalName>unwanted</finalName>
<classifier>unwanted</classifier>
</configuration>
</execution>
</executions>
</plugin>
Everything seems fine, until I discovered my main jar artifact is never installed in the .m2 directory. To correct this, I also added the maven-helper-plugin so that I manually attach any artifacts I produce from the assembler plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>attach-instrumented-jar</id>
<phase>verify</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}.jar</file>
<type>jar</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
This leads to an error I am unable to solve:
[ERROR] Failed to execute goal org.codehaus.mojo:build-helper-maven-plugin:1.9.1:attach-artifact (attach-instrumented-jar) on project my-project: Execution attach-instrumented-jar of goal org.codehaus.mojo:build-helper-maven-plugin:1.9.1:attach-artifact failed: For artifact {full-name-of-my-project.jar}: An attached artifact must have a different ID than its corresponding main artifact. -> [Help 1]
Is there a way to overcome this issue? I've checked for solutions, and most recommend using classifiers, but I want to install the main artifact as would the maven-jar-plugin. Other software we are developing will require the standard jar dependency, and we want to avoid complicating our setup by introducing classifiers unreasonably.
After some more trial and failures I happened to come with a working solution.
I am posting it here with the hopes to either be useful, or to have any issues with pointed to me, as I am not really confident if this is a reliable approach.
So, the error I received
An attached artifact must have a different ID than its corresponding main artifact.
meant to me that I cannot manually install "again" the main artifact. Since that artifact is not produced anymore by the maven-jar-plugin, it never gets scheduled for installation even if the file is present (the antrun copy task produces a jar with the same name).
Surprisingly, it needed a few little tricks to make this work again:
Re-enabled the maven-jar-plugin as it should be:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
</execution>
</executions>
</plugin>
This will produce the standard jar on the package phase, and most importantly, makes maven aware for it to be installed during the install phase.
Tweak the maven-antrun-plugin copy tasks to overwrite the already produced jar with the deterministic zip. The setup is nearly identical as in my question, so I am only adding the differences:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>...</execution>
<execution>
<id>step-3-rename-assembly-and-sources</id>
<phase>package</phase>
<configuration>
<target>
<copy file="${project.build.directory}/${project.build.finalName}-deterministic.zip"
tofile="${project.build.directory}/${project.build.finalName}.jar"
overwrite="true"/>
</target>
</configuration>
</execution>
. . .
</executions>
</plugin>
The copy operation now has overwrite="true" specified. Originally, the copy operation seemed to ignore files in the destination if they already exist, and what happened is that the maven-jar-plugin had already produced the default jar artifact when the copying occured. With this option set, the maven-antrun-plugin now overrides the former jar with the deterministic one, and the latter becomes a subject of the maven install phase.
Removed the setup from the build-helper-maven-plugin, so that the main jar artifact is not copied a second time:
<artifact>
<file>${project.build.directory}/${project.build.finalName}.jar</file>
<type>jar</type>
</artifact>
That's it, the correct jar is installed in the .m2 dir.
In case you don't have a plugin to create and attach main artifact for you, there is a more generic solution with Groovy Maven plugin:
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>set-main-artifact</id>
<phase>package</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
project.artifact.setFile(new File(project.build.directory, project.build.finalName + ".zip"))
</source>
</configuration>
</execution>
</executions>
</plugin>
Inspired by post https://stackoverflow.com/a/31513690/2053580 many thanks to https://stackoverflow.com/users/1314907/lukasz-guminski
My project can generate some additional help files automatically from the source code.
How do I have maven install these files into the generated JavaDoc package?
I couldn't fingure out how to have Maven:
run some class to generate the additional documentation, e.g. compile and launch src/main/java/mypackage/ListOptions.java aka mypackage.ListOptions to produce a list of all available options/modules/examples/etc. .
install the output files (I only could get Maven to install files from src/main/javadoc/resources into the site/apidocs/resources subfolder; but I want this documentation to live in the top level site/apidocs folder; more precisely I don't care about the site part at all, but about having a complete documetation in mypackage-0.1.0-SNAPSHOT-javadoc.jar; including non-Javadoc-generated auxillary information linked from javadoc).
Minimal example - Plugin configuration for maven:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<docfilessubdirs>true</docfilessubdirs>
</configuration>
</plugin>
Directory layout:
./pom.xml
./src/main/java/foobar/GenerateNonstatic.java
./src/main/javadoc/staticfile.js
./src/main/javadoc/resources/insubfolder.png
mvn package produces: javadoc in ./target/apidocs and ./target/foobar-0.0.1-SNAPSHOT-javadoc.jar. The file target/apidocs/resources/insubfolder.png ends up in folder target/apidocs/resources (and the .jar), but the staticfile.js is not installed.
How to run GenerateNonstatic.java to have the output included in the javadoc .jar is unclear to me. I don't see a hook to have exec:exec it run after javadoc, and before ./target/foobar-0.0.1-SNAPSHOT-javadoc.jar is built...
Long story, short answer. Both the javadoc:javadoc and javadoc:jar mojos have their drawbacks. The first is meant to build the javadoc for reporting; the latter will build the javadoc (into a different directory) and produce a jar package.
Some of the suggested answers did not work well because of this - they would execute javadoc twice.
But I noticed that javadoc does not care if the folder already exists or contains files.
So my solution is simple: generate the desired additional files in prepare-package, and the regular javadoc:jar task adds the regular javadoc and pacakges it nicely.
This will work as long as you don't intend to modify files generated by javadoc (which I, fortunately, don't - I only add additional documentation.
The resulting pom.xml is like this:
<plugins>
<!-- copy additional javadoc resources -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/apidocs</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/javadoc</directory>
<excludes>
<!-- overview.html is integrated by javadoc -->
<exclude>${basedir}/src/main/javadoc/overview.html</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- Generate additional files for javadoc -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<id>generate-extra-javadoc</id>
<phase>prepare-package</phase>
<goals>
<!-- java is okay, but you only can have one -->
<goal>exec</goal>
</goals>
<configuration>...</configuration>
</execution>
</executions>
</plugin>
<!-- Build JavaDoc -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Eric,
If you are uncomfortable modifying the javadoc executable, another option is to break apart your javadoc call into 2 separate steps (javadoc and jar) and make your call between them by manipulating the Maven build lifecycle via <phase> tag:
phase: generate-sources => maven-javadoc-plugin:javadoc
phase: compile => exec-maven-plugin:java
phase: package => maven-javadoc-plugin:jar
note: use exec:java, not exec:exec to run java classes
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>generate-javadocs</id>
<phase>generate-sources</phase>
<goals>
<goal>javadoc</goal>
</goals>
</execution>
<execution>
<id>attach-javadocs</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<id>generate-nonstatic-javadocs</id>
<phase>compile</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>foobar.GenerateNonstatic</mainClass>
</configuration>
</execution>
</executions>
</plugin>
To answer your first question: Run a commandline command with the Exec-Maven-Plugin or use the Maven-Ant-Plugin and embed custom tasks.
Eric,
Your example is indeed helpful. Please do try to always include concrete examples as much as possible when asking the question.
The simplest approach would be to write your own Alternate Javadoc tool and pass that into Maven via the <javadocExecutable> tag. This example comes from the link above:
<project>
...
<reporting> (or <build>)
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<javadocExecutable>C:\jdk1.6.0\bin\javadoc.exe</javadocExecutable>
...
</configuration>
</plugin>
...
</plugins>
</reporting> (or </build>)
...
</project>
Hope that helps.
I'm converting a largish Ant build to Maven. As part of the Ant build, we have several steps which created Java classes by invoking one of the project's classes, simplified as:
javac SomeGenerator.java
java SomeGenerator generated # generate classes in generated/
javac generated/*.java
I've split each generator in its own Maven module, but I have the problem of not being able to run the generator since it's not yet compiled in the generate-sources phase.
I've tried something similar to
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<id>generate-model</id>
<goals>
<goal>java</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<mainClass>DTOGenerator</mainClass>
<arguments>
<argument>${model.generated.dir}</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
Which sadly does not work, for the reasons outlined above. Splitting the code generators into two projects each, one for compiling the generator and another for generating the DTOs seems overkill.
What alternatives are there?
Using Maven 2.2.1.
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 the compile phase):
exec-maven-plugin for executing a main class able to generate my source files in target/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 module
maven-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, using maven-compiler-plugin. You can also exclude other source files.
Run generator to generate code
We can do it in process-sources phase, using exec-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>
We faced the same problem. We wanted to respect Maven's behavior as closely as possible, to have no problems with plugins and so on... Fighting Maven is just too expensive!
We realized that the update frequency of the generated code was usually very different from the one of the code that we manually write, so separating the code had very good performance characteristics for the build. So we accepted to have our generated classes as a dependency of the manually written.
We adopted the following structure, that had just one little change from a regular maven config, a change in the source directory.
Parent project : Generations
We created a parent project for all our generations.
It has a JAR type if it contains code to be compiled, otherwise POM.
There we have our generating code, in /src.
It can compile in /target as usual.
It runs the generation, each generator producing code in a sub-directory of /target.
Note: if you want several generated results in the same jar, just put them in the same sub-directory.
Child jar projects : Generateds
It is a subdirectory of the Generations project.
It has a JAR type.
The source directory points to the sub-directory in the parent's target.
<sourceDirectory>../target/generated1</sourceDirectory>
It compiles normally in its own /target directory.
That structure allows us to :
have as little modification to the standard maven layout as possible, so every maven command and plugin keeps working nicely.
scale nicely if you have several generators,
scale nicely if you want to generate several jars (we had a case wsdl2java where one generator produced code that should be split into several jars ; each child generated project would have the same source directory, but would be configured with an <includes> to handle only some of the classes).
I posted a minimal working setup here https://github.com/baloise/inlinesourcecodegenerator
It uses build-helper compiler and exec plugins and has all code in the same project.