Maven plugin dependency - using the source plugin in all my poms - maven

I would like to configure the use of the maven source plugin for all our projects. The way our projects are currently configured we have a parent pom that is inherited by all the projects. So, in order for all projects to use the maven source plugin, I did the following:
Defined the maven source plugin under build -> plugin management in the parent pom
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
In my project pom (the child pom), I have included the source plugin under build -> plugins
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
Could someone please tell me if this is the best way to configure this? Is there any way you can avoid specifying the source plugin in the child pom?

This is the best way.
To avoid having to add the plugin declaration in the child pom you could add it to the build/plugins section in the parent. The problem with that however is that EVERY child gets that invocation added even if it does not make sense if e.g. the child is a pom or ear packaging. You should therefore not do this..

Related

How to specify a default goal for a Maven plugin?

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.

Using profiles to exclude WAR modules from 'mvn install'

My parent pom defines 7 modules, 5 of which are dependency jars, and two are wars that depend on those jars.
Question: Is it possible to use maven profiles (or another solution) to define which modules are included when mvn install is run against the parent pom to exclude the two war packages?
I would then like to have a different profile (or another solution) to package the two wars. If that profile is run, the dependency jar modules should be rebuilt and installed only if they are missing from the repository.
You could use the build-helper-maven-plugin in your parent pom.xml file to create a new property based on the packaging (at runtime it would change from pom for the parent, to jar and war for the modules). This new propery could then be used to skip the maven-install-plugin dynamically.
A simple example:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<id>build-helper-regex-is-packaging-war</id>
<phase>validate</phase>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>only.when.war.is.used</name>
<value>${project.packaging}</value>
<regex>war</regex>
<replacement>true</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<skip>${only.when.war.is.used}</skip>
</configuration>
</plugin>
Doing so, the dynamic ${only.when.war.is.used} property would be set to true only when project.packaging would have value war and as such effectively skip the maven-install-plugin executions via its skip option.
You could then move this behavior to a profile and have different settings for jar and war, keeping them in a common place: the root pom.xml, thanks to their dynamic behavior.
Concerning the ability to detect whether an artifact has already been installed or not, there is no such an option on the official plugin documentation and I don't think you could have such a behavior by simply using the plugin.
You could however use the maven profile activation mechanism in case a file is missing (the installed file) and activate the profile accordingly.
You could have in a dynamic way (based only on standard properties) the following approach:
<profiles>
<profile>
<activation>
<file>
<missing>${settings.localRepository}/${project.groupId}/${project.artifactId}/${project.build.fileName}.${project.packaging}</missing>
</file>
</activation>
...
</profile>
</profiles>

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?

Change default pom.xml and project layout of Maven

I am just starting using maven and I use Apache Maven Shade Plugin a lot. Is it possible to add these code
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- put your configurations here -->
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
to default pom.xml. Yes, it can change setting.xml to make this plugin work with all project. But if I have some specific project which will not need this plugin, do I have to rewrite setting.xml again?
Another problem is that is it possible to change project layout of Maven. I use git a lot. Can I add sample .gitignore every time when I run mvn archetype:generate.
For you first issue, I think you can benefit from the parent POM:
http://books.sonatype.com/mvnex-book/reference/multimodule-sect-simple-parent.html
It's a defined POM file in which you put whatever you want. You publish it as a "pom" in your Maven repository and then, you can inherit from it in other projects. It is very convenient to lock dependency verions as well.
Your second issue seems more related to the archetype you are using than maven itself. You will probably have to create your own with a default .gitignore in it.

Maven Multi Module Project + root pom plugin

I have a maven multi module project why is it when I put this configuration:
<plugin>
<groupId>org.zeroturnaround</groupId>
<artifactId>jrebel-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<id>generate-rebel-xml</id>
<phase>process-resources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
in the root pom and mvn install the project no rebel.xml file is generated.
I can generate it using mvn org.zeroturnaround:jrebel-maven-plugin:1.1.3:generate but that only creates the rebel.xml under target/classes and does not include it in the jar\war package.
But when I put the above configuration in the individual maven module it does generate it during install and includes it in the package as per process-resources
But I don't want to duplicate the plugin in all modules, but only put it in the root pom and during install is should generate the rebel.xml file and include in the package.
Am I missing how maven works?
Turns out it was my bad I had put the plugin by error in the pluginManagement section when I thought I had put it in the build>plugins section where it should be, now it's working fine. Many Thanks

Resources