How to specify a default goal for a Maven plugin? - maven

I've defined a Maven plugin with multiple goals. Currently users run my plugin as follows:
<plugin>
<groupId>myGroupId</groupId>
<artifactId>myArtifactId</artifactId>
<version>someVersion</version>
<executions>
<execution>
<goals>
<goal>myGoal</goal>
</goals>
</execution>
</executions>
</plugin>
but I've seen other plugins, like maven-compiler-plugin and Flyway, that don't require specifying an execution: https://flywaydb.org/getstarted/java
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>5.2.4</version>
<configuration>
<url>jdbc:h2:file:./target/foobar</url>
<user>sa</user>
<locations>
<location>classpath:db/migration</location>
</locations>
</configuration>
</plugin>
How do I specify the goal that should run by default when users exclude the <executions> block?

AFAIK, there are not default goals for Maven plugins.
You can configure a plugin without adding a goal. But this does not execute the plugin.
The plugin must be either executed explicitly on command line (like flyway:migrate) or is executed automatically through the lifecycle (like compile:compile or jar:jar).

I assume you are using the Java5 Annotations to mark your plugin as available mojo? (and not the javadoc way of living).
The #Mojo annotation has a defaultPhase attribute.
Once a user adds the plugin into the build these defaults (if set) will be used.
The Flyway Migrate Mojo does it this way too.
The compiler plugin is a bit of a bad example, as it is part of the default plugin bindings of the maven life-cycle itself. So the phase itself will know what mojo to run.
These are the docs for the maven plugin api, the one for using annotations is nearby.
If it is not your plugin, you can put the configs you want into a parent pom into the pluginManagement section.

Related

How to add test-jar as aspectLibrary in Maven

I have an aspect that I want to use in my test-classes. I don't want to add it to the main jar, as it would pull in test libraries like junit and mockito. While there's a configuration setting to add an aspectLibrary, it always adds the main jar, there's no way to specify the test-jar.
My aspectj plugin looks like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<aspectLibraries>
<aspectLibrary>
<groupId>aspect.test</groupId>
<artifactId>general</artifactId>
<type>jar</type>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
I actually want to specify test-jar but that doesn't seem possible. Without the it defaults to the jar (obviously).
I also might have to configure aspectj-maven-plugin for the compile and test-compile goal... but first I need to know how to specify the test-jar. Any suggestions are welcome.
Please read the Maven JAR Plugin documentation, chapter How to create a jar containing test classes. There are two options listed:
the easy way: using type "test-jar" (will not work here)
the preferred way: creating a normal JAR containing only test classes, then importing it with scope "test"
We will choose the preferred way because it solves your problem. So basically you do the following:
Create a separate module for test helper aspects/classes, put everything under src/main/java, not src/test/java. AspectJ Maven plugin should have an execution with <goal>compile</goal> for that module.
Add that module as a test-scoped dependency wherever you need the test aspects
Refer to the module as an <acpectLibrary> from AspectJ Maven plugin and also be careful to only use <goal>test-compile</goal> in your plugin execution for that module so as to avoid to have the aspects woven into production code or to get error messages because the dependency has test scope and is unavailable for normal compile.
Because I do not want to fully quote 3 POMs and several classes here, I have created a little GitHub sample project for you. Just clone it, inspect all the files and their respective locations and - be happy. ;-)

configuring maven plugin with a custom packaging

I have written a custom maven plugin which works in package phase of maven's default life cycle. In addition I have added a custom packaging type to it. In order to support the custom packaging type I have introduced components.xml so it will override the default maven life cycle. In the component/configuration/lifecycles/lifecycle/phases/package section of component.xml I have added my plugin to execute in package phase.
When I use my plugin I pass the configuration to the plugin through the pom.xml as follows;
<build>
...
<plugins>
<plugin>
<groupId>sample</groupId>
<artifactId>sampleArtifact</artifactId>
<extensions>true</extensions>
...
<executions>
<executions>
<phase>package</phase>
<goal>generate</generate>
<configuration>
//Configuration goes here.
</configuration>
</executions>
</executions>
...
</plugin>
</plugins>
...
</build>
Problem:
the configuration I passed into mojo as above is not getting set in the mojo. However, if I set the plugin configuration in one level below the tag(where the executions tag present), then it works. Since this plugin works in package phase I need the plugin configuration passed in through as above. Without custom packaging, the above configuration works well. Any thoughts on what I miss here?

Using CodeNarc with Maven

I am trying to integrate CodeNarc with a Maven-based Groovy project. The documentation on the site for the CodeNarc Maven plugin is minimal. The usage aspects I am trying to understand are:
How to point to the custom rule sets and where in the project to place them?
How to fail the Jenkins build if any of the rules are violated.
Currently I am able to run CodeNarc using command
mvn codenarc:codenarc
When I add the 'reporting' section to the POM file (as described at http://www.mojohaus.org/codenarc-maven-plugin/usage.html) and run
mvn site
no CodeNarc report is generated. I get this warning
[WARNING] No URL defined for the project - decoration links will not
be resolved
but it is not clear where it is related to CodeNarc.
What is the proper way of using CodeNarc with Maven?
I just did it, in case you still need the tip. You can hook the execution of the plugin by creating a "plugin" entry under "build"->"plugins"->"plugin". Here is what I have.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>codenarc-maven-plugin</artifactId>
<version>0.18-1</version>
<configuration>
<sourceDirectory>${project.basedir}/src/main/groovy</sourceDirectory>
<maxPriority1Violations>0</maxPriority1Violations>
<maxPriority2Violations>0</maxPriority2Violations>
<maxPriority3Violations>0</maxPriority3Violations>
</configuration>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>codenarc</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
Note the "maxPriority_Violations" values. This is what makes the build fail in case of violations.
I dont use any custom rules, but it seems you can define your own rules by setting the "rulesetfiles" configuration option. See configuration options here: http://www.mojohaus.org/codenarc-maven-plugin/codenarc-mojo.html
Example of project with this configuration: https://github.com/tveronezi/faceid/tree/master/faceid-web

What is meant by plugin goal in Maven speak?

I am a newbie to Maven . I am reading up Maven - The complete reference and came across the term Plugin Goals under the Build settings category of a pom.xml file :
In this section, we customize the behavior of the default Maven build.
We can change the location of source and tests, we can add new
plugins, we can attach plugin goals to the lifecycle, and we can
customize the site generation parameters.
Can you please explain with an example what is meant by attaching plugin goal to the lifecycle?
A plugin goal is a thing that a plugin does. Attaching a plugin goal to the lifecycle is saying to maven: when you are going through the lifecycle and are in this phase, trigger this plugin to do whatever the plugin does. This might sound rather confusing, so let's go through an example:
I want to deploy my application to the server each time I call mvn install. For this, in the build section of the pom , I add the following configuration:
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.1.1.Final</version>
<configuration>
...
</configuration>
<executions>
<execution>
<id>deploy-jar</id>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Take a look at the execution part: this describes how to attach the deploy goal of the jboss-as-maven-plugin to the install phase of the build lifecycle.
For further explanation of the maven lifecycle and it's phases, read this

How to execute maven plugin _after_ all module builds finish

Specifically I am trying to run maven-javadoc-plugin but whenever I change the version numbers on the parent/aggregator pom and all of the children, the first time I run the build it fails because javadoc runs first and can't find any of the new version packages from the modules because they haven't been built yet.
I usually end up having to comment javadoc out for one build and then add it back in once the packages are available in nexus for the new version. However, this likely means that I've been building javadoc on one build old source jars all the time.
I've read suggestions of putting another module in that depends on the other ones but I don't think i can get a module to build the javadoc for peer modules. Having it in the parent builds all of the javadoc for all of the modules, I just need it to happen later. Thanks. Here's my javadoc plugin config.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<id>generate-javadoc</id>
<phase>package</phase>
<goals>
<goal>aggregate</goal>
</goals>
<configuration>
<aggregate>true</aggregate>
<links>
<link>http://java.sun.com/javase/6/docs/api</link>
<link>http://java.sun.com/javaee/5/docs/api</link>
</links>
<maxmemory>512</maxmemory>
<doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
<docletArtifact>
<groupId>org.umlgraph</groupId>
<artifactId>doclet</artifactId>
<version>5.2</version>
</docletArtifact>
<additionalparam>
-inferrel -inferdep -outputencoding utf8 -hide
java.* -collpackages
java.util.*
-qualify -postfixpackage
-nodefontsize 9 -nodefontpackagesize 7
</additionalparam>
</configuration>
</execution>
</executions>
</plugin>
One way to get around this problem is not to invoke javadoc plugin in the normal maven lifecycle phase; instead run it separately.
To be specific, remove <phase> tag from the above plugin definition.
Run mvn install javadoc:javadoc from parent.
This will build and install all the modules and the parent and then run javadoc on them.
Is your javadoc plugin declaration in the <build> part of your pom. You should consider moving it to the <reporting> part see this link.

Resources