Something bother me a lot...
On a big project with many dependencies, some of them are set as SNAPSHOT in Maven2.
The matter is that it seems i can't get the sources through Eclipse without loading the project or fixing the dependency to the last release.
For debugging, it's really annoying me...
EDIT
This is what i get in eclipse maven console:
26/08/10 11:31:46 CEST: Downloading http://repo-maven/archiva/repository/snapshots/com/blabla/1.1-SNAPSHOT/blabla-1.1-20100824.213711-80-javadoc.jar
26/08/10 11:31:47 CEST: Could not download sources for com.blabla:blabla:1.1-20100824.213711-80
On archiva i can see the deployed stuff i want to retrieve in eclipse...
Repository snapshots
Group ID com.blabla
Artifact ID blabla
Version 1.1-20100824.213711-80
Packaging jar
Parent com.blabla bla 1.1-SNAPSHOT (View)
Other Versions 1.1-20100824.213535-79
I can download sources of this artifact with my browser but not within Eclipse... Any idea?
The matter is that it seems I can't get the sources through Eclipse without loading the project or fixing the dependency to the last release. For debugging, it's really annoying me...
Well, these modules are probably not publishing source JARs as part of the "regular" build process (i.e. outside the release). If these modules are under your control (which is my understanding), configuring the Maven Source Plugin to produce source JARs for them and deploying them in your corporate repo should solve the problem. From the Usage page:
Installing the sources along with your artifact
There are two ways to do this. You can
either bind this plugin to a phase or
you can add it to a profile. The goals
source:jar-no-fork and
source:test-jar-no-fork are preferred
for binding the goal to the build
lifecycle.
Installing the sources using a phase binding
Here is how you would configure the
plugin in your pom.xml to run
automatically during the verify phase:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
We are using the verify phase here
because it is the phase that comes
before the install phase, thus making
sure that the sources jar has been
created before the install takes
place.
Installing the sources using a profile
If you want to install a jar of your
sources along with your artifact
during the release process, you can
add this to your pom.xml file:
<project>
...
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
...
</project>
Using a profile would probably be a good idea so that building source JARs will only be done by the build running at the CI server level but not on developer machines.
Related
When running mvn versions:display-dependency-updates for the Version Maven Plugin I see lots of things like this:
[INFO] org.slf4j:slf4j-api ........................... 1.7.36 -> 2.0.0-alpha7
But just because I'm not using the alpha version of a later version doesn't mean I'm not using the latest available release version. Another Stack Overflow answer indicated that I can set up a rules.xml file to ignore versions like *.-alpha*, putting something like this in my POM:
<configuration>
<rulesUri>file:///${project.basedir}/rules.xml</rulesUri>
</configuration>
My question: is this rules.xml file inheritable? If I put it in a separate project in a parent POM of <packaging>pom</packaging>, published to Maven Central, will the child POMs pick it up? Or will the child projects look for a rules.xml file in the child project directory?
I want to configure the versions-maven-plugin in the parent POM (as I do already) and run mvn versions:display-dependency-updates on any child POM or descendant POM. How can I set up the ignore rules in the parent POM so that these version ignore rules will be picked up when I check for dependency updates in a child POM? (Is there no way to include the rule within the POM itself?)
Or will the child projects look for a rules.xml file in the child project directory?
Yes, if you define the rules.xml file via ${project.basedir} it will resolve to the current local base directory of the child project. I've verified this with a simple parent-child pom setup. So that will not work, unless you duplicate the rules file in every project.
If you wish to include the plugin configuration and ruleset in the parent pom without duplicating the rules file, you have two options:
If you have your ruleset xml file hosted at, for example, http://www.mycompany.com/maven-version-rules.xml then the following configuration in your corporate pom would ensure that all projects use this rule set.
<configuration>
<rulesUri>http://www.mycompany.com/maven-version-rules.xml</rulesUri>
</configuration>
or
You can provide your ruleset xml file also within a jar, if you want to distribute your ruleset xml as Maven artifact. Therefore you have to declare the containing jar as direct dependency of the versions-maven-plugin and to use classpath as protocol.
<configuration>
<rulesUri>classpath:///package/foo/bar/rules.xml</rulesUri>
</configuration>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>version-rules</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
Source:
https://www.mojohaus.org/versions-maven-plugin/version-rules.html
The configuration in the pom only has rudimentary includes and excludes filters. Those will allow you to exclude any dependency as a whole, but not specific update versions. As far as i can tell from the available documentation there is no way to define version rules in any other way.
See
https://www.mojohaus.org/versions-maven-plugin/examples/advancing-dependency-versions.html
Update 09-2022
In the github ticket we found in the comments we can see the following update:
It looks like a feature like this has recently been implemented by #369. Please see #318 where it's possible to provide inclusion and exclusion filters for determining which dependency patterns will be considered. Thanks to that, you can rule out patterns such as .*-beta. or .*_ALPHA, albeit not using regexp, but simple asterisk wildcards.
This will land in today's release (2.12.0).
This will add the following features:
Version 2.12.0 will introduce new arguments: dependencyIncluded, dependencyExcludes, dependencyManagementIncludes, dependencyManagementExcludes.
With the following example configuration in pom.xml given:
<profile>
<id>display-dependency-updates</id>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>display-dependency-updates</goal>
</goals>
<configuration>
<dependencyIncludes>org.apache.maven.*:doxia*</dependencyIncludes>
<dependencyManagementIncludes>com.puppy*:*</dependencyManagementIncludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
This will also be implemented for filtering plugin and pluginManagement, but that will probably be added in a later release:
So, I've just added the missing plugin- and plugin management filtering which works likewise. I really doubt it will land into today's release though.
Pasting my answer here from Github, because I think it might benefit others.
Provided you have a directory called rules-test in your project containing the rules template file:
<ruleset comparisonMethod="maven"
xmlns="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0
https://www.mojohaus.org/versions-maven-plugin/xsd/rule-2.0.0.xsd">
<ignoreVersions>
<ignoreVersion type="regex">${ignoredVersions}</ignoreVersion>
</ignoreVersions>
</ruleset>
Then, in your main project, create the following profile:
<profile>
<id>rules-test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>rules-test</directory>
<filtering>true</filtering>
</resource>
</resources>
<outputDirectory>${project.basedir}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.12.0</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>display-dependency-updates</goal>
</goals>
<configuration>
<rulesUri>file://${project.basedir}/compiled-rules.xml</rulesUri>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
If you then execute the following Maven target:
mvn -P rules-test "-DignoredVersions=.*-(M\d*|.*-SNAPSHOT)" clean validate
then you will get a dependencies report using the filter in the -DignoredVersions argument (filtering out both *-M* and *-SNAPSHOT).
And if you put your ignoredVerions property in your project instead of passing it as a -D argument, then it will be inheritable!
I have a maven project that I just added some features to and in order to do so I had to add a local jar dependency. I have added this jar file to the lib folder of the project on Github, and I want to make it so anyone who downloads the project off Github can install that jar to their m2 directory without having to use the maven install:install-file command through command line. The POM file has the dependency already but I need a way to programmatically install the jar file when building the snapshot with mvn install.
Thoughts?
Option 0:
Deploy the jar file to a public or comany-wide maven repository. If the project producing this jar is also a git(hub) project, consider using a service like Jitpack
Option 1:
Ugly, but could work.
<dependency>
<groupId>com.bar</groupId>
<artifactId>foo</artifactId>
<version>42</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/foo-42.jar</systemPath>
</dependency>
Option 2:
Even more ugly, but could work even better.
<build>
<plugins>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-foo</id>
<goals>
<goal>install-file</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<groupId>com.bar</groupId>
<artifactId>foo</artifactId>
<version>42</version>
<file>${project.basedir}/lib/foo-42.jar</file>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I have a number of Maven projects being built my Jenkins server. These projects have dependencies on each other, e.g.
service-base -> java-base -> pom-base
In other words, the Maven project service-base depends on the Maven project java-base. Naturally, my POM files look like this:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>my.com</groupId>
<artifactId>service-base</artifactId>
<dependencies>
<dependency>
<groupId>my.com</groupId>
<artifactId>java-base</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
The issue is that none of my Maven projects have "releases" per-se, since I'm using continuous integration to release my changes. Currently, I allow artifact overwriting in my Maven repo and keep all of my versions at 1.0.0. This is because I release my packages many times a day and changing the versions in all the POM files each time I submit a new package version.
Ideally, what I would like is for Jenkins to generate a new version, e.g. 1.0.{BUILD_NUMBER} and then for it update the dependencies all the way up the dependency tree.
Question: Is this possible? Or does anyone have any other solutions to versioning?
Here is how I achieved the same, using Maven profiles, Maven classifiers and Jenkins parametrized builds.
You can define a jenkins profile (or whatever name you prefer) in the pom of the concerned projects. This profile will not be active by default, so your local builds will keep on working as usual. However, this profile will be activated on the Jenkins builds (via the -Pjenkins option on the Maven execution).
How this profile look like in the project at the top of the hierarchy:
<profiles>
<profile>
<id>jenkins</id>
<properties>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<packaging>${project.packaging}</packaging>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>generate-default-version</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>${BUILD_NUMBER}</classifier>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>install-default-version</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>${project.build.directory}/${project.build.finalName}-${BUILD_NUMBER}.${project.packaging}</file>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
What is the profile doing?
We are using the Maven Jar Plugin to generate on the package phase yet another artefact for the same project, so the project will create the normal jar plus another jar having as classifier the BUILD_NUMBER (i.e. myproject-1.0.jar and myproject-1.0-4567.jar)
We are also using the Maven Install Plugin to install the additional artefact (the myproject-1.0-4567.jar) into the local Maven cache (so it will be visible to other dependent projects)
We need to define some properties for the Install Plugin, otherwise the install-file will not work
Hence, when on your Jenkins build you will execute the following:
mvn clean install -Pjenkins -DBUILD_NUMBER=${BUILD_NUMBER}
Jenkins will actually pass its BUILD_NUMBER to Maven, which will use it as defined in the jenkins profile and create (and install) an additional artefact for us using it as classifier.
Fine, now we have a dynamically created artefact using the Jenkins build number and available for other projects/builds.
But how other projects can use it?
We define in the dependent projects another profile (or again called jenkins for coherency) and re-define the dependency we now need at runtime:
<profiles>
<profile>
<id>jenkins</id>
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>test</artifactId>
<version>1.1.0</version>
<classifier>${BUILD_NUMBER}</classifier>
</dependency>
</dependencies>
</profile>
</profiles>
Note: we are actually overriding as part of the profile a dependency and saying we want that specific classifier for it. Which classifier? The BUILD_NUMBER classifier, which will be available in the local Maven cache of the Jenkins server because installed by the previous build.
But how can the dependent build know which build number and as such which classifier to use, dynamically?
Using Jenkins parametrized builds and the Jenkins Parametrized Trigger plugin.
So, to summarize:
Provider project defines the profile to create additional classifier
Consumer project defines the profile to use as dependency a specific classifier
If a project is Provider for others and Consumer of others, it can then merge the two approaches above in the same profile
The first Jenkins build activates this specific profile and pass to Maven its build number
The downstream Jenkins builds are triggered by the first, which is passing them its build number via the Parametrized Plugin
Each downstream build would then resolve the classifier specified by the parameter and, if required, also create yet another classifier for its own build (according to its profile)
Using this approach, you local builds will keep on working as usual and no classifier would be used, while Jenkins builds would use an additional classifier used across them.
I am using properties-maven-plugin to read a external property file under root dir to maintain the version of parent module since there are quite a number of sub-modules in my project and the dependency tree is kinda deep.
It works fine when I build locally and install the artifacts into local repo but got the 401 error when I try to use "mvn clean deploy" to publish them to Nexus. I am pretty sure this is caused by the ineligible artifact name(releaseurl/{external.version}), external.version is supposed to be the property read from the external file. However, it ended up not being read and it just worked fine when I explicitly declare the version in the project.parent.version tag. Any thoughts or workaround? or even how you handle the version control when trying to use same version for parent and child in all the modules when dealing with a multi-module porject.
The maven pom for the plugin is as below, I saw some comments online regarding the phase, not sure if it will work if change initialize to something else:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>external-file.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
With intent to get m2e 1.0 working correctly I have had to specify the lifecycle mapping:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<versionRange>[2.0.2,)</versionRange>
<goals>
<goal>process</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
But then I get this warning:
[WARNING] The POM for org.eclipse.m2e:lifecycle-mapping:jar:1.0.0 is missing, no dependency information available
[WARNING] Failed to retrieve plugin descriptor for org.eclipse.m2e:lifecycle-mapping:1.0.0: Plugin org.eclipse.m2e:lifecycle-mapping:1.0.0 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.eclipse.m2e:lifecycle-mapping:jar:1.0.0
if I run some specific maven task for example mvn clean install findbugs:findbugs (If I run only mvn clean install then there is no such message)
I know that the problem is that this POM does not exists, because it is only defined to hold the mapping information. (m2e lifecycle-mapping not found)
Anyway, I want to keep my build clean, without any warnings, so how can I get rid of this specific one? (My CI server checks that there is no warning.)
I use Maven 3.0.2 and tried Maven 3.0.3 too, but the same result.
My team works around this problem by wrapping the relevant configuration in a profile:
<profile>
<id>only-eclipse</id>
<activation>
<property>
<name>m2e.version</name>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
...
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
This a known bug with WONTFIX resolution. The suggested solution is the simplest in my opinion:
mvn archetype:generate -DgroupId=org.eclipse.m2e -DartifactId=lifecycle-mapping \
-Dversion=1.0.0 -DarchetypeArtifactId=maven-archetype-mojo
and install this project.
m2eclipse 1.7.0 introduced an alternative, namely an XML processing instruction.
In the original example, you would simply “annotate” every <execution> of the maven-processor-plugin’s process goal with
<?m2e execute?>
See the release notes for more details on the syntax and further options.
This solution is now deprecated, I would recommend using the "profile" solution by #ctrueden which is the accepted answer!
While not the most clean solution, when you use a repository manager in your company or are on your own, in the mean time you may do this:
- Checkout https://github.com/mfriedenhagen/dummy-lifecycle-mapping-plugin.
- Run mvn install when you are on your own
- Run mvn deploy -DaltDeploymentRepository=REPO_ID::default::YOUR_THIRDPARTY_REPO_URL when you have a repository manager like Nexus or Artifactory.
- See https://github.com/mfriedenhagen/dummy-lifecycle-mapping-plugin/blob/master/README.creole as well.
Regards
Mirko
Now there's now better solution (for the error messages in Eclipse only).
Press CTR+1 on the error Plugin execution not covered by lifecycle configuration: org.codehaus.mojo:buildnumber-maven-plugin:1.1:create-timestamp (execution: default-create-timestamp, phase: validate) and then select this option:
This works with org.eclipse.m2e.editor.xml_1.2.0.20120903-1050.jar plugin (maybe earlier also)