26

I would like to retrieve from the command line the groupId, the artifactId & the version of a Maven project.

The proposed solution in this topic "How to get Maven project version to the bash command line" is to use the following plugin:

mvn org.apache.maven.plugins:maven-help-plugin:2.2:evaluate -Dexpression=project.artifactId

It works well but I can't figure out how to set, at the same time, the project.groupId, project.artifactId & project.version to the -Dexpression argument.

I would avoid launching 3 times the Maven command with a different -Dexpression argument each time...

Thks


For the moment, I retrieve data by doing the following:
local pom_groupid=`mvn org.apache.maven.plugins:maven-help-plugin:2.2:evaluate -Dexpression=project.groupId |grep -Ev '(^\[|Download\w+:)'`
local pom_artifactid=`mvn org.apache.maven.plugins:maven-help-plugin:2.2:evaluate -Dexpression=project.artifactId |grep -Ev '(^\[|Download\w+:)'`
local pom_version=`mvn org.apache.maven.plugins:maven-help-plugin:2.2:evaluate -Dexpression=project.version |grep -Ev '(^\[|Download\w+:)'`
haridsv
  • 9,065
  • 4
  • 62
  • 65
gudepier
  • 3,362
  • 6
  • 22
  • 26

8 Answers8

29

Here's another approach that doesn't require creating a Maven plugin even though Olivier has shown that it is pretty easy to make one.

mvn -q -Dexec.executable=echo -Dexec.args='${project.groupId} ${project.artifactId} ${project.version}' --non-recursive exec:exec 2>/dev/null

Note that this is tailored to the linux environment. On windows you could probably create a batch file that prints its input or something.

One drawback of this approach is that you may have to add | grep -v "something" to the very end of the command above (after the 2>/dev/null) to filter out some text that maven prints to stdout. In my case I only had one line of text to filter that'll only appear at my company.

Credit where it is due: I adapted this info from this other StackOverflow thread.

haridsv
  • 9,065
  • 4
  • 62
  • 65
user3483102
  • 303
  • 3
  • 5
  • One drawback for this approach is that all the dependencies need to be resolved before extracting the properties. There exists cases where you do not want to resolve the dependencies and simply want the properties declared within the pom file. In that case, `help:evaluate` is still the better choice. – GJ. May 06 '20 at 21:04
  • Hi! I'm quite new to this. How did you specify the plugin using this command? Is it something like this? org.codehaus.mojo exec-maven-plugin 3.0.0 What execution should I put in it? – Loren Jan 14 '22 at 01:38
23

This is the cleanest solution available:

mvn org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate \
-Dexpression=project.groupId -q -DforceStdout

mvn org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate \
-Dexpression=project.artifactId -q -DforceStdout

mvn org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate \
-Dexpression=project.version -q -DforceStdout

Advantages:

  • This works fine on all operating systems (OS X, Ubuntu, Windows etc.) and on all shells (bash, zsh etc.)
  • [very important] This works fine even if groupId or version is inherited from parent pom.xml.
    • Note that xmllint-based solutions fail when POM properties are inherited!
  • Zero dependency on external tools! (notice that I'm not using any echo or grep)

Alternatively, you can add this entry in your pom.xml, under plugins section:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-help-plugin</artifactId>
    <version>3.2.0</version>
</plugin>

and then run commands compactly as follows:

mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout
mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout
mvn help:evaluate -Dexpression=project.version -q -DforceStdout

Please note:

  • maven-help-plugin version 3.2.0 (and above) has forceStdout option. You may replace 3.2.0 in above command with a newer version from the list of available versions of mvn-help-plugin from artifactory, if available.
  • Option -q suppresses verbose messages.
Manu Manjunath
  • 6,201
  • 3
  • 32
  • 31
  • 1
    Didn't work for me on Powershell. I had to wrap the expression in single quotes `-Dexpression='project.groupId'` – jajube Jun 14 '23 at 15:13
  • How can I use above command to get artifactId for multi-module project ? – SuhasD Jul 10 '23 at 10:39
9

A simpler command, derived from @Patrick's answer to get the "GAV" format:

echo '${project.groupId}:${project.artifactId}:${project.version}' | mvn -N -q -DforceStdout help:evaluate

In case of an external *.pom file to evaluate, this command may be useful:

echo '${project.groupId}:${project.artifactId}:${project.version}' | mvn -N -q -DforceStdout help:evaluate -f <path-to-pom-file>
bitfox
  • 2,281
  • 1
  • 18
  • 17
JohnW
  • 614
  • 6
  • 6
  • 2
    To get different properties and assign them to shell variables: `IFS=: read id version <<< "$(echo '${project.artifactId}:${project.version}' | mvn --quiet --non-recursive help:evaluate -DforceStdout)"` – GJ. May 06 '20 at 21:10
  • @GJ. Thanks for the IFS + read suggestion. – RH Becker May 21 '21 at 18:56
6

In bash, consider the following lines I use to get them.
It uses xmllint and some string manipulation.

GROUP_ID=`echo -e 'setns x=http://maven.apache.org/POM/4.0.0\ncat /x:project/x:groupId/text()' | xmllint --shell pom.xml | grep -v /`
ARTIFACT_ID=`echo -e 'setns x=http://maven.apache.org/POM/4.0.0\ncat /x:project/x:artifactId/text()' | xmllint --shell pom.xml | grep -v /`
VERSION=`echo -e 'setns x=http://maven.apache.org/POM/4.0.0\ncat /x:project/x:version/text()' | xmllint --shell pom.xml | grep -v /`

I hope this helps.

Eldad Assis
  • 10,464
  • 11
  • 52
  • 78
6

You can specify multiple expressions for the maven-help-plugin (so you only have to run it once) and then extract them from the captured output by grep'ing for the 'key' you specified:

output=$(printf \
    'LOCAL_REPOSITORY=${settings.localRepository}\n'\
    'GROUP_ID=${project.groupId}\n'
    'ARTIFACT_ID=${project.artifactId}\n'\
    'POM_VERSION=${project.version}\n0\n' \
  | mvn help:evaluate --non-recursive )

localRepository=$(echo "$output" | grep '^LOCAL_REPOSITORY' | cut -d = -f 2)
groupId=$(echo "$output" | grep '^GROUP_ID' | cut -d = -f 2)
artifactId=$(echo "$output" | grep '^ARTIFACT_ID' | cut -d = -f 2)
pomVersion=$(echo "$output" | grep '^POM_VERSION' | cut -d = -f 2)

Other solutions that parse the pom.xml work for simple use cases, however they fall short if you need to access something that is either not defined in the pom.xml (settings.localRepository) or a potentially derived value (project.version).

Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
Patrick Crocker
  • 193
  • 2
  • 6
  • Thank you, this works great! I added options `-q -DforceStdout` to avoid some clutter. – Alex Feb 04 '21 at 07:50
5

I had an issue with echo and interactiveMode false + a custom profile.. turns out you can specify all 3 (or 4 if you need the packaging) in the expression by omitting the first ${ and last } ex:

mvn -N -q -DforceStdout help:evaluate -Dexpression='project.groupId}:${project.artifactId}:${project.packaging}:${project.version' -f ./xpp3-1.1.3.4.O.pom

Or more elegantly (this will include packaging) with project.id:

-Dexpression=project.id

This is because the source code wraps the expression:

handleResponse( "${" + expression + "}", output );

Source / Credits: https://github.com/paul-hammant/maven-plugins/blob/master/maven-help-plugin/src/main/java/org/apache/maven/plugins/help/EvaluateMojo.java

The error I got when using interactiveMode false and a profile with -P:

[ERROR] Maven is configured to NOT interact with the user for input. This Mojo requires that 'interactiveMode' in your settings file is flag to 'true'.
Miguel Pereira
  • 1,781
  • 16
  • 14
  • Unfortunately, project.id returns groupId:artifactId:packaging:version. The dependency:copy goal, for example, requires groupId:artifactId:version[:packaging[:classifier]]. – Steve Mitchell Feb 02 '22 at 04:44
4

Sometimes, we forget how easy it is to tailor Maven to our need : here is a very simple custom plugin that do one thing, concatenate groupId,artifactId and version and send it to out.

Check it out, run mvn clean install (local) or mvn clean deploy(repository) to make it available in your environment.

Then run mvn my.helper.maven.plugin:helper-maven-plugin:me or mvn helper:me (after adding <pluginGroup>my.helper.maven.plugin</pluginGroup> to your <pluginGroups> in your Maven settings.xml) to have the following line displayed on console :

my.help.me={project.groupId}:{project.artifactId}:{project.version}

To filter out everything but this line, all you have to do is running :

mvn helper:me| grep ^my.help.me=

or even simpler :

mvn -q helper.me
Olivier
  • 3,465
  • 2
  • 23
  • 26
  • Thanks for your plugin, it works well. but unfortunately the environment can't be upgraded with "custom" plugins (settings.xml) and the _builded pom_ is in read only too. Currently I've to use common/default tools for this script... KR – gudepier Dec 09 '14 at 14:48
  • As long as you have a way to push the plugin in your maven repo, using the "long" command should work, without the need to modified settings.xml or pom.xml. But I understand that sometimes, 'no' means 'no' ;) – Olivier Dec 09 '14 at 15:32
3

I prefer avoiding new dependencies where I can solve the solution easily. Using powershell:

[xml]$pomXml = Get-Content .\pom.xml

# version
Write-Host $pomXml.project.version

# groupId
Write-Host $pomXml.project.groupId

# artifactId
Write-Host $pomXml.project.artifactId
Avner
  • 4,286
  • 2
  • 35
  • 42