Is it possible to get Maven dependencies in a property at run-time? - maven

I'm working with a situation where we are using the LATEST and RELEASE keywords in our POM for a certain dependency (both the dependency and the project are owned by us, so we control what is LATEST and RELEASE...and we only support one version at a time). Using these keywords allows us to minimize maintenance needed after a release.
There is a step in the build process that must copy DLLs from the unpacked dependency, but since we don't specify a specific version we have the version number of the unpacked dependency hard-coded and have to update it after every release. Is there a way get the version of this dependency at run-time from a Maven property?
The properties goal of the maven-dependency-plugin (http://maven.apache.org/plugins/maven-dependency-plugin/index.html) gets the location of the artifact in the local repository (which is not what I'm looking for). The depends-maven-plugin (shown here: http://team.ops4j.org/wiki/display/paxexam/Pax+Exam+-+Tutorial+1) can generate a file that contains the various dependencies and their versions, but using that would require having a process read the file and utilize that information. I'm wondering if there is a more "Maven way", such as accessing a property for the dependency version.
EDIT: For clarification, we need the version number so we can get to the directory of the unpacked dependency to copy files.

I'm not sure what you mean with 'maven way' but I did something like this after looking at the same plugins you already mention:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
project.properties.put('firstdependencyinthepom', project.dependencies[0]['version'])
project.properties.put('seconddependencyinthepom', project.dependencies[1]['version'])
</source>
</configuration>
</execution>
</executions>
</plugin>
and then I was able to refer to versions of these dependencies with ${firstdependencyinthepom} and ${seconddependencyinthepom} respectively.

Related

Pomless Tycho build + maven release plugin

I have a pomless tycho build which I want to release with the maven release plugin. The issue I have is that I get errors from the git plugins for the generated .polyglot.build.properties even though it is not included in the configuration of the git-add goal.
Parent pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
<localCheckout>true</localCheckout>
<preparationGoals>
org.eclipse.tycho:tycho-versions-plugin:${tycho.version}:update-eclipse-metadata
build-helper:parse-version
org.apache.maven.plugins:maven-scm-plugin:1.9.5:add
org.apache.maven.plugins:maven-scm-plugin:1.9.5:checkin
</preparationGoals>
<completionGoals>
org.eclipse.tycho:tycho-versions-plugin:${tycho.version}:update-eclipse-metadata
build-helper:parse-version
org.apache.maven.plugins:maven-scm-plugin:1.9.5:add
org.apache.maven.plugins:maven-scm-plugin:1.9.5:checkin
</completionGoals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.9.5</version>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>add</goal>
<goal>checkin</goal>
</goals>
<configuration>
<includes>**/META-INF/MANIFEST.MF,**/feature.xml,**/*.product,**/category.xml,release.properties</includes>
<excludes>**/target/**</excludes>
<message>Changing the version to reflect the pom versions for the release</message>
<pushChanges>false</pushChanges>
</configuration>
</execution>
</executions>
</plugin>
The error I get:
fatal: pathspec 'my.plugin/.polyglot.build.properties'
did not match any files
After looking at the source code of tycho-pomless, polyglot, and maven-release, I conclude pomless build can't work with maven release. I need to add pom.xml
The reason is:
tycho-pomless uses polyglot, which creates an temporary pom from the build.properties, which is deleted when the JVM exits
maven release:prepare spawns a child maven process to execute the preparation goals. When the child process finishes, this deletes the temporary files. The available mavenExecutorId values are "invoker" which invokes a new process, and "forked", which forks the process. Which means both spawn a new JVM.
So in conclusion, it looks like tycho-pomless (or any polyglot build, really) and maven-release are incompatible in the presence of preparation goals, and there seems to be no workaround. The possible workaround of executin the preparation goals in the same JVM seems to be unavailable. So the solution is adding a pom.xml
Check first is this is similar to this question, where the plugin does finds the files it should add, but, when creating the command line, it does not respect the correct root directory.
See if the path mentioned in pathspec 'my.plugin/.polyglot.build.properties' the correct one.
Double-check if your POM and folder hierarchy is at the right place, meaning in the project root folder.
The OP kutschkem refers in the comments to:
the .polyglot.build.properties is a temporary file, deleted by the release:prepare child process exit.
But release plugin picks it up as the pom of the project to checkin.
That might be why I see in Tycho/Reproducible Version Qualifiers
<jgit.ignore>
pom.xml
.polyglot.build.properties
</jgit.ignore>

How to get the current build version in Maven/Tycho

I have read that the ${project.version} property should be used to obtain the full version of a project.
But if I use this property in a build to pass the currently built version to an external build process, its values is alway 1.0.0-SNAPSHOT where I would need something like 1.0.0-20160220-1234. The phase in which the external build step is called is `packageĀ“.
The tycho-packaging-plugin is configured to produce timestamps like this:
<configuration>
<format>yyyyMMdd-HHmm</format>
</configuration>
And the resulting artifacts do have timestamps in the versions/names
I use Maven 3.3.3 with Eclipse Tycho 0.24, however, with previous versions of Tycho the behavior is the same. Not sure if Tycho behaves differently than plain Maven in this regard.
The build is run with
mvn clean verify
in the directory of the master pom.
The actual project I am using this for is Extras for Eclipse. The external build step is invoked in line 129 of the 'repository' child pom.
I have also used the echo plug-in in the above-mentioned child pom to diagnose the problem like this:
<plugin>
<groupId>com.soebes.maven.plugins</groupId>
<artifactId>maven-echo-plugin</artifactId>
<version>0.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>echo</goal>
</goals>
</execution>
</executions>
<configuration>
<echos>
<echo>actual version: ${project.version}</echo>
</echos>
</configuration>
</plugin>
The output is the same as the external build receives: 1.0.0-SNAPSHOT.
What do I need to do or which property do I need to use to get the qualified version of the current build?
From my understanding the ${project.version} property should hold the qualified version, e.g. 1.0.0-20160218-1234. But either there is a bug in Maven/Tycho or my understanding is plain wrong. And I would be happy if someone could clarify this.
However, I found the ${qualifiedVersion} property that is set by the tycho-packaging:build-qualifier mojo. This property holds the expected value.
Note that even though the documentation states
is assigned to the project property qualifiedVersion
the property cannot be accessed through ${project.qualifiedVersion}. It needs to be referenced as ${qualifiedVersion}.

Get and unpack latest version of dependency without a pom file

Is this possible? I need to be able to use Maven to download a dependency to a specific directory and unpack it there, not knowing the version number. I can get close, with maven-dependency-plugin:2.7:get providing the "dest" param and using "LATEST" in the artifact param. It gets the resource (a tarball) downloaded to where I want it. But now I'd like maven to also extract it.
So since versions newer than 2.7 recommend using maven-dependency-plugin:copy if I need the dest param, I thought I could use maven-dependency-plugin:unpack (the same as copy, but unpacks the dependency in the process). However, both copy and unpack require the artifact have a version number, so I'm stuck.
Also tried using maven-dependency-plugin:get with no dest, then maven-dependency-plugin:unpack-dependencies in the same command, but seems unpack-dependencies requires a pom file to work. Bummer.
Is there a way to get the version number of the latest and somehow make it used in the unpack command, without any sort of bash trickery (stuck using just mvn commands)?
For unpacking, try this:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>package</phase>
<id>Unpack</id>
<configuration>
<target>
<untar src="some_dependency_*.tar" dest="${proj.home}"/>
</target>
</execution>
</executions>
</plugin>

read rivision number of pom file

I want to use svn revision number of pom file as its version.
In pom.xml, if we use buildnumber-maven-plugin, we need to define scm repository url, so that it can check to repository and use buildnumber.
But i want to ask that when we have checkedout code to our system, isn't there any way to get buildnumber without using scm urls. As revision number is stored as subversion in property of each file. we can see it if we right click on file and go to properties.
I want to use buildnumber in version tag of pom and other module's buildnumber in their vaersion tag in dependencies to them.
So if i can store all subversion numbers initially, infact earlier than resolving dependencies, then these subversions can be placed in version of module in dependency and also in version of each pom file.
Problem is that dependencies are resolved before plugin reads version number ( this is what i think), so it cannot resolve expression.
I tried it using properties-maven-plugin to write pom's version number in a file and then read it in other module's pom which is dependent on it. But dependencies are to be resolved before execution of any plugin is started.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<id>pre-clean-config</id>
<phase>validate</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${project.basedir}/../app.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
So, it is not working.
Starting with Maven 3.2.1 you can define a property ${revision} which you can use in your versions like this:
<project...>
<groupId>..</groupId>
<artifactId>...</artifactId>
<version>1.0-${revision}</version>
...
The result of this you need to give a property while calling Maven like this:
mvn -Drevision=123456 clean package
This will also work in dependencies etc. Currently one drawback is that you always creating a release from maven's point of view.

maven dynamic version

I searching a way to dynamise the version of my artifact depending on the profile.
Often I use the -SNAPSHOT suffix when I build for dev or preprod. But the database connection depends on the profile and I never know if the latest SNAPSHOT version was build using the dev or preprod profile.
The idea would be having a version like this
<version>1.0${suffix}</version>
with ${suffix} =
"" when building with prod profile
"-SNAPSHOT" when building with preprod profile
"-DEV-SNAPSHOT" when building with dev profile
Is there a way of achieving this ?
thanks
edit :
My goal is when I go on jenkins to build my jar, I build the same "tagged" version of my project with the 3 profiles and it deploys 3 differents artifacts.
Actually I tag my project and go build with the prod profile, then I modify the version to add -SNAPSHOT, commit, move the tag, re build with preprod profile, and then repeat for the dev profile.
Seeing your answer to #Michael-O comments, i'd recommend to configure the maven assembly plugin to create the final name of the artifact according to a system property set on each profile. For example:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create jar according to profile</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>${project.artifactId}-${project.version}_${profile}</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
where ${profile} should be a property set to a different value on each profile (for doing that you can see this question). I dunno if there's a variable to get the profile being currently used to build, that would be another question :)
It is not necessary to reassemble the JAR, I would rather use a standard mech: Simply specify a classifier for your artifact in the jar plugin.
Otherwise I would filter a properties in a given properties file and read that in your app. This what I do, e.g. system.env=prod|test|localdev.

Resources