maven execution of plugin goal? - java

i am new to maven and learning how and when phases/goals get executed in plugin
Say i have below code snippet in my pom
<plugin>
<groupId>org.codehaus.modello</groupId>
<artifactId>modello-maven-plugin</artifactId>
<version>1.4</version>
</plugin>
Now if i execute mvn install, all phases(and all goals corresponding to each phase) of modello that comes prior to install will be executed. Right?
But if do below modification to introduce specific goal, only one goal i.e java goal will be executed
(as it under generate-sources phase which comes prior to install phase). Is that correct?
<plugin>
<groupId>org.codehaus.modello</groupId>
<artifactId>modello-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
</plugin>

No, it doesn't work like that. First of all, please use mvn verify (instead of install), unless you really want your project to be copied to your local repository.
If you only specify a plugin, which is not part of the default lifecycle (e.g. maven-compiler-plugin is already specified for the default lifecycle, all jars need to compile, right?), nothing will happen. So you need to specify which goals need to be executed within an execution-block. In some cases the goal has a default phase to bind to, e.g. modello:java binds by default to the generate-sources-phase. In this case you don't have to specify a <phase> in the execution-block.

Related

Maven plugin config goal inside execution tag

I noticed maven plugins has goals and they are bound to different phases. But it seems some goals will only be executed after we explicitly config them in side execution tag. For example, maven-jar-plugin has two goals jar and test-jar. If you don't config test-jar goal explicitly inside execution tag then it will not be executed. It will only be triggered with below config where test-jar is explicitly config inside execution tag
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>test-compile</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
But for goal jar whether you config it with execution tag or not, it will always be triggered. In this case, I wonder to trigger a goal of a plugin should we config it inside execution tag or not? I didn't see official doc has any clarification on this either. Thanks.
The jar goal is by default bound to the default life cycle (jar) so it's triggered automatically.
All plugins which are bound by the default life cycle (for example maven-compiler-plugin etc) will run automatically during a build.
Any other goals which are not bound will not run automatically and have to be bound manually if needed.
All goals like the jar goal of the maven-jar-plugin should never being bound manally... because they are already bound to the life cycle.
Furthermore you should always check the documentation of the appropriate plugin (here the maven-jar-plugin) and check the goal page for the text: Binds by default to the lifecycle phase: package.
This means you can omit the <phase>..</phase> part of your configuration because the plugin knows the life cycle phase when it should start.

Maven Release Plugin auto increment custom format version

I want to be able to auto-increment a java project's release version by using non-interactive mode in Maven release plugin (mvn -B release:prepare). However I do not want to use the default Maven versioning schema.
The schema that I would like to use is <major>.<minor>.<bugfix>-SNAPSHOT. I did manage to do this inside the pom file, however Maven tries to increment it as follows:
1.0.0-SNAPSHOT
1.0.1-SNAPSHOT
1.0.2-SNAPSHOT
...
However I want to be able to have control on this and while some of the time I do have bugfixes and the above incrementing works, most of the times I would like to release minor releases and therefore an increment that looks like this:
1.0.0-SNAPSHOT
1.1.0-SNAPSHOT
1.2.0-SNAPSHOT
...
You can handle this via build-helper-maven-plugin like this:
mvn build-helper:parse-version versions:set \
release:prepare \
-DdevelopmentVersion =\${parsedVersion.majorVersion}.\${parsedVersion.nextMinorVersion}.0-SNAPSHOT \
release:perform
This will set the 1.1.0-SNAPSHOT as next development version..The next time you call release plugin it will make 1.1.0 from it and will automatically increment 1.1.1-SNAPSHOT if you don't like just use the call above...
"The maven way"is to follow maven rules, or to create a custom plugin.
Maven plays nice as long as you want to do what it expects that you want to do.
Maybe solution for you would be to use just "1.1" most of the cases, and if you want to do a bugfix release, then to add 3rd number by hand.
However if you really wish to fight against maven, there is a possibility to setup properties from within some other plugin.. i.e. like this:
<profile>
<id>customversionnumber</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<executions>
<execution>
<id>set-release-version</id>
<phase>initialize</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
project.properties.setProperty("releaseVersion","1.3.0")
System.out.println("releaseVersion set to 1.3.0")
</source>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Then, you'd invoke release plugin like this
mvn -Pcustomversionnumber initialize release:prepare.
And it will release it as "1.3.0" regardless whats in 'version' tag. I'll have to code that number increment on your own of course.

How to execute code after eclipse:eclipse in maven?

I want to run some code after the eclipse goal of the eclipse plugin (eclipse:eclipse) runs.
The documentation of the eclipse plugin says that the generate-resources phase is execute prior to the eclipse goal, but it doesn't mention any phase that is executed after.
I wanted to include the code with the gmaven-plugin but I can't find the right configuration:
<execution>
<id>delete_generated_sources_from_cp</id>
<phase>generate-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<providerSelection>1.7</providerSelection>
<source>
modifyClasspath.groovy
</source>
</configuration>
</execution>
Simply add the plugin you want to execute to your project. If you add an execution of the plugin to the phase process-resourcesit will execute after the eclipse plugin if you run mvn process-resources (or any phase after process-resources)
You could also invoke them directly: mvn eclipse:eclipse otherplugin:goal
eclipse:eclipse is not good way for executing the codes. I mean if you want to import project to eclipse, you should use 'eclipse:eclipse' otherwise you shouldn't.
Executing the code is depend on you codes; if this is web based, you should deploy it in your application server. If it has executable main class, you should execute it with 'java' command.
I wanted to include the code with the gmaven-plugin but I can't find the right configuration
I could not understand what you mean. could you explain more ..

maven skip tests with compilation errors

Are there an option to skip tests with compilation errors? Just ignore them or treat them as failed?
The maven-compiler-plugin is responsible for compiling your tests during the test-compile phase. This plugin is configured to fail the build if any test classes fail to compile. You could experiment with the failOnError configuration. But I doubt you'll get the results you expect. The compilation process stops immediately when it encounters a compilation error. So potentially issue free classes may not have been re-compiled. Therefore there will be no guarantee the .class files you execute during the test phase will be 'up to date' with the corresponding .java source files.
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<failOnError>false</failOnError>
</configuration>
</execution>
</executions>
</plugin>
Not recommended...
mvn -DskipTests=true clean compile
Remember, with great power comes great responsibility.
use the following command to skip the entire test source folder. Through there are compilation errors in the test classes maven wont consider those, if you use the following command.
mvn clean install -Dmaven.test.skip=true
-DskipTests usually works. For instance, mvn install -DskipTests.
If you need to tell maven strictly to ignore - use -Dmaven.test.skip=true. This will force all the plugins and compiler to ignore the tests
Edited: Looks like -DskipTests=true also works!

Generating new sources via Maven plugin after compile phase

I have a Maven project within which I need execute two code generation steps. One generates some Java types, then the second depends on those Java types to generate some more code. Is there a way to have both of these steps happening during my build?
At the moment my steps are:
execute first code generation plugin (during generate-sources)
add directory of generated types to build path
execute second code generation plugin (during compile)
However my problem is that anything generated by the second code generation plugin will not be compiled (because the compile phase has finished). If I attach the second code generation plugin to an earlier phase, it fails because it needs the classes from the first code generation plugin to be present on the classpath.
I know I could split this into two modules with one dependent on the other, but I was wondering if this could be achieved in one pom. It seems like a need a way to invoke compile again after the normal compile phase is complete.
Any ideas?
You can always configure two executions of the compiler plugin, both tied to the compile phase. In one you include the extra stuff:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<id>one</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration></configuration>
</execution>
<execution>
<id>two</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<compilerArgument>-verbose -bootclasspath ${java.home}\lib\rt.jar</compilerArgument>
</configuration>
</execution>
</executions>
<plugin>
You may try as well <includes><include>path/</include></includes>
According the official documentation:
When multiple executions are given that match a particular phase, they are executed in the order specified in the POM, with inherited executions running first.
But I quite not get what you exactly want.
http://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html
The obvious solution (generate code after the compile phase) doesn't work since Maven doesn't allow to reorder the phases.
The correct solution is to use modules. You need two: The first module contains the code generator. In the second module, you can use the generator from the first module to generate something in the generate-sources phase.
The big advantage of this approach: You can never get caught in some kind of loop (like "A" needs generated code which needs "A"). So your build will be more simple and you will spend less time hunting odd bugs.
[UPDATE] In my projects, I run the code generator from tests. Without a special option, the files are generated into the temp folder and compared to the sources. That allows me to see when I have unexpected changes in my generated code (which I put under version control).
When the system property is set, the source files are overwritten and I can commit the changes to my VCS.

Categories