Maven plugin prefix resolution doesn't seem to work as expected - maven

I've created a MOJO for a specific application need. I've followed maven's guidelines in naming the plugin so that I didn't have to mention the full
mvn groupId:artifactId:version:goal
for executing my plugin(I've named it to match the format ${prefix}-maven-plugin).
I've even included the 'goalPrefix' property in the plugin POM's configuration section. Here's a sniff of what I did to my plugin's POM:
<configuration>
<goalPrefix>${prefix}</goalPrefix>
</configuration>
But I'm still unable to execute my plugin just using mvn ${prefix}:goal since it complains it can't find the plugin in any repository. I've still had to use mvn groupId:artifactId:version:goal Any idea why?

By default, Maven does only recognize plugins with the group IDs org.apache.maven.plugins and org.codehaus.mojo. If your plugin has a different group ID (which should be the case), you need to add this group ID as plugin group to your Maven settings.xml file:
<settings>
...
<pluginGroups>
<pluginGroup>the.groupid.of.my.plugin</pluginGroup>
</pluginGroups>
...
</settings>
Take a look at the Maven Settings Reference for further details.

Related

How to replace a property in a POM in a Maven/Jenkins job?

I have a project with client and server components. Both have their own Maven multi-module build projects.
The correct server version must be referenced in various frontend modules. To accomplish this I set a property in my client parent POM like this:
<properties>
<server.version>1.2.3</server.version>
</properties>
Now I'd like to update the version number in the POM (i.e. not just injecting a different version from the command line with -D...) during/after a Jenkins build job. Is there a way to do this?
I found the com.google.code.maven-replacer-plugin:replacer Maven plugin which works perfectly for my case. It accepts an xpath and a regex to define what to replace in an XML file.
Example plugin configuration:
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<configuration>
<file>${project.basedir}/pom.xml</file>
<xpath>/project/properties/server.version/text()</xpath>
<token>^.*$</token>
<value>${newServerVersion}</value>
</configuration>
</plugin>
And the plugin can be run for each affected maven module:
mvn --non-recursive replacer:replace -DnewServerVersion=xxxx
At itembase we use Jenkins Pipeline Plugin. It comes with some useful built in functions like for example readMavenPom and writeMavenPom. So in your build pipeline you could do something like:
def pom = readMavenPom file: 'pom.xml'
//Do some manipulation
writeMavenPom model: pom
Did you check maven versions plugin?
(Tbe website is shutdown but the plugin page is still avaiable in google cache)
mvn -DnewVersion=<version> versions:set

Maven install goal does not generate pom for modules

I'm running a multi-module maven project and have an unexpected behavior. First time I'm seeing this...
My parent module configures the install plugin, defining its classifier.
<plugin>
<artifactId>maven-install-plugin</artifactId>
<configuration>
<generatePom>true</generatePom>
<classifier>${env}</classifier>
</configuration>
</plugin>
<!-- ... -->
<modules>
<module>webapp-formation</module>
<module>db-formation</module>
</modules>
But when I'm running mvn install the .pom files are not generate for my modules. Only my parent is associated with a .pom file in my repositories. Thus trying to browse to my module's artifact on Archiva (after running mvn depoy of course!) it simply fails. I can browse to the parent but not its children.
So... I need to add the undocumented attribute generatePom to my plugin configuration to have the .pom files generated --copied would be a better word actually-- for all my modules. --I said undocumented attribute because this attribute is documented only for the install-file goal which is not the one ran by default. The install goal is not expecting that attribute...
Of course, if I do not configure my install plugin --so not configuring the classifier-- I have no problem and all .pom files are generated properly.
For you guys, is that a normal behavior? Something that you have already seen? Or should I just file a bug?
Thanks,
Olivier.
What you describe as an undocumented attribute is simply wrong, cause the attributes are specific on a goal base which means the given configuration will not change anything, cause the generatePom attribute is only valid for install-file goal. So you can remove it.
In general such configuration does not make sense, cause if you have different environments you should go a different way. Just removed hte configuration with <classifier>${env}</classifier> as well and try to deploy via:
mvn clean deploy

How does Maven resolve plugin versions?

I'm reading the docs and still confused as to how Maven is deciding which versions of plugins to download.
For example, consider this simple scenario:
an empty local repository
a default settings.xml
run a simple maven command. for example, mvn archetype:generate for the maven-archetype-quickstart as described in the Maven in 5 Minutes doc.
After running the command, the first thing Maven does is download a bunch of plugins.
Some of the plugins Maven is downloading include:
maven-clean-plugin-2.4.1
maven-install-plugin-2.3.1
maven-deploy-plugin-2.5
Why those versions?
The most recent version of these plugins are:
maven-clean-plugin-2.5
maven-install-plugin-2.5.1
maven-deploy-plugin-2.8.1
I looked at the LATEST version metadata for maven-clean-plugin and it's 2.5
It's not that I necessarily want to force Maven to use different versions of these plugins, I just want to understand WHY it's resolving to those versions.
I'm using Apache Maven 3.0.3
Maven defines 3 lifecycles in META-INF/plexus/components.xml:
1. Default Lifecycle
Default lifecycle are defined without any associated plugin. Plugin bindings for these lifecycles are defined separately for every packaging in META-INF/plexus/default-bindings.xml
e.g. Plugin bindings for jar packaging
<phases>
<process-resources>
org.apache.maven.plugins:maven-resources-plugin:2.6:resources
</process-resources>
<compile>
org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile
</compile>
<process-test-resources>
org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
</process-test-resources>
<test-compile>
org.apache.maven.plugins:maven-compiler-plugin:2.5.1:testCompile
</test-compile>
<test>
org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
</test>
<package>
org.apache.maven.plugins:maven-jar-plugin:2.4:jar
</package>
<install>
org.apache.maven.plugins:maven-install-plugin:2.4:install
</install>
<deploy>
org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
</deploy>
</phases>
2. Clean Lifecycle
clean lifecycle is defined directly with its plugin bindings.
<phases>
<phase>pre-clean</phase>
<phase>clean</phase>
<phase>post-clean</phase>
</phases>
<default-phases>
<clean>
org.apache.maven.plugins:maven-clean-plugin:2.5:clean
</clean>
</default-phases>
3. Site Lifecycle
Site lifecycle is defined directly with its plugin bindings.
<phases>
<phase>pre-site</phase>
<phase>site</phase>
<phase>post-site</phase>
<phase>site-deploy</phase>
</phases>
<default-phases>
<site>
org.apache.maven.plugins:maven-site-plugin:3.3:site
</site>
<site-deploy>
org.apache.maven.plugins:maven-site-plugin:3.3:deploy
</site-deploy>
</default-phases>
If you want to override these default plugin version you can do it from command prompt as follows
mvn org.apache.maven.plugins:maven-clean-plugin:2.0:clean
instead of
mvn clean:clean
Every version of Maven binaries has certain versions of plugin versions hardcoded. That's to make a somewhat reproducible build in the cases when user doesn't provide his own version information. Which you are encouraged to do and once you populate <pluginManagement> section with the plugin versions of your choice, the build will start using it.
It becomes quite clear if you use -X option when building your projects. Please, check my answer in another thread:
https://stackoverflow.com/a/48874533/4470135

read Maven variable from properties file using profile

I want to read a maven variable for configure a build plugin from a properties file. It's not needed in and further project files e.g. context files.
1) made a profile (it works, can use mvn ... -P private)
<profile>
<id>private</id>
<properties>
<env>private</env>
</properties>
</profile>
2) created the filter file with this content (it works)
foo.path=/home/foo/path
3) try to configure the plugin (does not work)
<build>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>foo-plugin</artifactId>
<version>${foo-plugin.version}</version>
<configuration>
<!--<fooPath>home/foo/path></fooPath> that works -->
<fooPath>${foo.path}</fooPath> <!--works not -->
</configuration>
...
</build>
Thx a lot
The name of your property is 'env' but you don't use env anywhere in your configuration.
When Maven docs mention "filter files" they usually mean a file used when processing resources (i.e. copying resources from /src/main/resources to target/classes). As far as I know the properties in those files aren't used for plugin configuration out-of-the-box. I have used the Codehaus properties-maven-plugin:read-project-properties goal do do what you are attempting. Make sure you bind the goal to the lifecycle before any plugins that need the properties for config.
Also, see this answer; you may load properties used to configure other plugins, but not to configure core Maven project elements.

How to tell Maven to ignore a dependency if failed to resolve it?

I have a dependency which I have installed in Maven local repository and is being used locally but is not available on deployment server. I use that dependency using Class.forName(...) so there will be no problem if it's missed from classpath on deployment server.
Is there any way to tell Maven to ignore a dependency if it failed to resolve it?
I doesn't seem that <scope> or <optional> can solve this problem, but it may be possible to do it with <profiles> if there is any way to activate/deactivate a profile based on dependencies availability.
Short answer: no.
Long answer: Once dependency is declared - either in common part or in an active profile - it must be resolvable when Maven attempts it; otherwise the build fails.
If maven allowed the requested behavior, the reproducibility of build would suffer a lot.
If obscurity and irreproducibility is not an issue for you, here is a hint how to do it:
call external ant from your pom.xml, using either exec-maven-plugin or maven-antrun-plugin
in the ant code, use artifact:dependencies from Maven Ant Tasks
wrap it in ant-contrib's trycatch block
In any case, I strongly discourage including such things into maven build. Having it as separate functionality, invoked via ant from commandline, might often be enough.
assuming the missing dependency is only important in the local environment you can use a combination of profile and activation via your .m2/settings.xml
You remove the dependency from your general dependencies and move it as a referenced dependency into a profile of your pom.xml (Project level profile) and activate the profile through your m2/settings.xml.
You may also remove the dependency completly from your pom.xml and move the dependency into a profile which resides in your .m2/settings.xml (User level profile)
see the introduction to profiles section
another way which fits your needs maybe better
The activation of the above mentioned profile based on the presence of the file in .m2/repository/local/dependency/1.0.0-Snapshot/local.jar
<profiles>
<profile>
<activation>
<file>
<exists>/home/user/.m2/repository/local/dependency/1.0.0-Snapshot/local.jar</exists>
</file>
</activation>
...
</profile>
</profiles>
Bizarrely, I had a problem with maven where it would say "cannot resolve dependency" (of some weird transitive dependency that didn't exist anymore), but it only failed with that error message if my ~/.m2/settings.xml had a
got my jars from a local repository
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>a name</id>
<url>http://somewhere/local/a</url>
</repository>
If I changed it to mirror, it would not fail.
<mirrors>
<mirror>
<id>a name</id>
<name>an awesome description</name>
<url>http://some/where/local</url>
<mirrorOf>external:*</mirrorOf>
(same repo). Go figure.
Please try to exclude the dependencies from the POM
<executions>
<execution>
<id>***failed dependency Id***</id>
</execution>
</executions>

Resources