Does the Maven Versions Plugin read rules also from classpath? - maven

The Maven Versions Plugin supports the defintion of rules to customize the version resolution process for goals as versions:display-plugin-updates or versions:display-dependency-updates. The location of the rules file can be specified by the rulesUri and the functionality behind this is provided by Maven Wagon.
Therefore I would like to know if it is also supported to provide a rule set within a Jar? I would like to one rule set for multiple projects.

A patch by me has been released with version 2.5 of the Versions Maven Plugin
Now it is possible to create a version rules file and to place it on the classpath.
This example below shows how to reference a rules file called rules.xml
which is provided in a jar on the classpath:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<rulesUri>classpath:///rules.xml</rulesUri>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>your.organisation</groupId>
<artifactId>rulesspec</artifactId>
<version>1234</version>
</dependency>
</dependencies>
</plugin>
Please keep in mind that the provided URI must start with classpath://.

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.

Exclude Java package from dependency jar

I want to use jar from third party vendor. But in this jar I have old version of Java package org.osgi.framework I need to find some way to exclude the package from the main project. Something like this:
<dependency>
<groupId>com.ibm</groupId>
<artifactId>com.ibm.ws.admin.client</artifactId>
<version>8.5.0</version>
<exclusions>
<exclusion>org.osgi.framework</exclusion>
</exclusions>
<type>jar</type>
</dependency>
Can you recommend some solution?
Although a better solution would be to re-pack the dependency (without the unwanted package) with a classifier (as described in this answer) and publish it on your enterprise Maven repository (or install it into your local Maven cache, if it's a personal project), below is a different solution which should also suit your needs.
You could have a multi-module Maven project, having a module with just this dependency and in it you could use the Maven Shade Plugin and its filters property as explained in its official example.
As per documentation, the filters element:
Archive Filters to be used. Allows you to specify an artifact in the form of a composite identifier as used by artifactSet and a set of include/exclude file patterns for filtering which contents of the archive are added to the shaded jar
In your case, the following configuration should apply the filter:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>com.ibm:com.ibm.ws.admin.client</artifact>
<excludes>
<exclude>org/osgi/framework/**</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
The generated jar from the package phase should not contain that package any longer. As part of the Maven output you should see:
[INFO] --- maven-shade-plugin:2.4.3:shade (default) # test-checksum ---
[INFO] Including com.ibm:com.ibm.ws.admin.client:jar:8.5.0 in the shaded jar.
[INFO] Replacing original artifact with shaded artifact.
You can verify the content of the generated jar, the filtered package should not be there.
Then, the output of this module will have the "new"/filtered jar you were looking for. Then the consumer module would just need to have a dependency on this module and as such have the filter applied.
An example of such a multimodule project would be:
+ aggregator/parent project
- filtered-dependency-module (applying the shade filter)
- consumer-module (having dependency on the filtered module)
Update
Further note: in the module which applies the filter, you should declare the dependency as optional so that the consumer module doesn't bring it in transitively again.
<dependencies>
<dependency>
<groupId>com.ibm</groupId>
<artifactId>com.ibm.ws.admin.client</artifactId>
<version>8.5.0</version>
<optional>true</optional>
</dependency>
</dependencies>
Optional doesn't affect the module itself, only the consumer one. And the Shade plugin will keep on working (I re-tested it, just in case).

Maven test jar including dependencies

My project is divided into several modules, one of them is common which is supposed to be used to other modules.
In this module there are TestUtils which I want to be able to use from other modules.
My libraries does not seem to be added to the test-jar. How can I achieve this?
+ common
++ lib
++ src
+++ test
++++ java
++++ resources
+ pom.xml
My pom.xml contains some libraries which I include via system path, such as:
<dependency>
<groupId>com.ibm</groupId>
<artifactId>com.ibm.disthub2.dhbcore</artifactId>
<version>5.3.07</version>
<scope>system</scope>
<systemPath>${basedir}/lib/dhbcore.jar</systemPath>
</dependency>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Simple answer: Not possible. The test-jar is only intended for compiled classes under the folder src/test/java inclusive src/test/resources but not for supplemental jar files.
Apart from that using a system scope is in general a bad idea.
Best is to put such jars into the company nexus and use it as a usual dependency. A lib folder in a Maven project is generally in indicator of build smells and should be avoided.
BTW: Why are you using such old versions of maven-jar-plugin (2008 version 2.2). Current version version 2.5 from this year.

Can I have maven artifact run maven plugin when it is installed?

I have created a Maven plugin (called unpackTemplates) that unpacks a dependency jar file and copies resource files (in this case, templates) from it into a specific location in a project.
Right now, I put the following into the pom file of every project that has a dependency with templates. It looks like:
<project>
<groupId>DuriansAreDope</groupId>
<artifactId>DuriansAreDope</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugin>
<groupId>mycorp</groupId>
<artifactId>unpackTemplates</artifactId>
<version>1.0</version>
<executions>
<execution>
<configuration>
<groupId>com.mycorp.lib</groupId>
<version>1.0</version>
<artifactId>Lib-With-Templates</artifactId>
</configuration>
<goals>
<goal>unpackTemplates</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
<pluginManagement>....</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.mycorp.lib</groupId>
<artifactId>Lib-With-Templates</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
The above project pom works for us. It calls the plugin and the plugin does it's job. However, we'd like to avoid adding the plugin section to the pom of every project.
It would make more sense to put that plugin section in the dependencies pom. This way the project pom does not need to be modified beyond adding the <dependency> tags as usual. And the dependency has it's plugin run wherever it is installed.
I've seen that the pom file for Gson contains a <build><plugins>...</plugins></build> section in it. When I give my dependencies the following pom files, however, the plugin is not run (although the dependency is found, downloaded, installed, etc correctly).
<project>
<groupId>com.mycorp.lib</groupId>
<artifactId>Lib-With-Templates</artifactId>
<version>1.0</version>
<build>
<plugin>
<groupId>mycorp</groupId>
<artifactId>unpackTemplates</artifactId>
<version>1.0</version>
<executions>
<execution>
<configuration>
<groupId>com.mycorp.lib</groupId>
<version>1.0</version>
<artifactId>Lib-With-Templates</artifactId>
</configuration>
<goals>
<goal>unpackTemplates</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
<pluginManagement>....</pluginManagement>
</build>
</project>
Any ideas what I'm doing wrong, or if the Gson pom is simply doing something else entirely?
(NB: The groupId/version/artifactIds in <configuration> are necessary because they are (string) parameters to the plugin; presumably if I got the run-straight-from-dependency approach working I could refactor them away, but again, it's not even running the kludgy version with parameters.)
two points:
First I agree with khmarbaise in that you don't need a plugin of your own for those tasks. To unpack to a specific location you can use dependency:unpack-dependencies and outputDirectory parameter.
If you need more configuration you can use the assembly plugin to structure your artifact (which you want to unpack).
For the second point it seems to me that you want to use the contents of your lib-with-templates in many projects. Why don't you add the plugin and dependency to a parent pom which you include in every pom where you need it? Then you don't need to declare it in "every pom". If you don't really need it in every pom you can put it in a profile and choose a proper activation for it.
HTH!

How do i get specific version ID as property in pom.xml with maven

My pom contains a version number following a sequence similar to 2.0-SNAPSHOT, at the same time we build the project with a manifest file, that needs parts of that version number since other projects are dependent on the specific version, however to simplify parts of the development we use 2.0 as the implementation version, so we dont have to switch between 2.0-SNAPSHOT and 2.0 in our dependency setup i would like to know if its possible to exclude the -SNAPSHOT from the ${project.version} so we dont have to maintain a variable manually?
For such purposes the build-helper-maven-plugin is the right one like this:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>parse-version</id>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
It will provide the following properties:
parsedVersion.majorVersion
parsedVersion.minorVersion
parsedVersion.incrementalVersion
parsedVersion.qualifier
parsedVersion.buildNumber
Apart from that it sounds strange that you need the 2.0 as a released version where you don't have released the artifact yet. So you should think about using the maven-release-plugin to release artifacts which will change the version for your current project a like.

Resources