Can Maven ignore a missing system property? - maven

If I have the following in my pom file:
<properties>
<mySystemProperty>${mySystemProperty}</mySystemProperty>
</properties>
When I build using "mvn clean install -DmySystemProperty=someData", it builds successfully. If I build it using "mvn clean install", where I don't need to specify the system property, Maven gives me this error:
Resolving expression: '${mySystemProperty}': Detected the following recursive expression cycle in 'mySystemProperty'
Is there a way to get maven to ignore the missing system property? If not, is there a way to default it?

Solved it. Using the same name for the system variable and maven variable caused the problem. Renaming the system variable fixed the error.
<properties>
<mySystemProperty>${sysProperty}</mySystemProperty>
</properties>

Related

In maven, can I define a variable used in another pom?

I'm getting an error when running maven build (unable to load a dependency).
[ERROR] Failed to execute goal on . . .
Could not transfer artifact my.group:libme1:${someVariable} from/to . . .
I believe that the developer that published this artifact was supposed to be setting the variable ${someVariable} but didn't. I think this is a bug but I'm trying to work around it by setting the variable.
The POM for the JAR I'm depending on my.group:libme1:1.2.3 looks like this (snippet highlighting the issue):
<groupId>my.group</groupId>
<artifactId>libme1</artifactId>
<parent>
<groupId>my.group</groupId>
<artifactId>libme1-parent</artifactId>
<version>${someVariable}</version>
</parent>
I tried defining it by adding -DsomeVariable=1.2.3 on the command line but it didn't work. For example, this command
mvn -DsomeVariable=1.2.3 clean install
should work based on Baeldung's article but doesn't.
I also ran:
mvn -DsomeVariable=1.2.3 help:effective-pom
and I see the variable being set, so I know he POM I'm using has that defined, but for some reason another POM doesn't pick up that value (or that is how it appears to me).
Is there any way to set the variable so it can be used in another POM? I'm guessing this is not possible.
Searching for an answer I found:
The maven doc
https://maven.apache.org/settings.html#Activation
If you know that this is bug, please let me know. I'm also reaching out to the publish of the artifact to ask them how this is supposed to work.
Basically the dependency's pom is invalid, the reasoning is following:
maven allows developers to do following things:
define dependencies in parent pom
impose restrictions on dependencies via <dependencyManagement> in both current and parent pom
use placeholders ${...} in <version> element, which somehow get resolved via system properties and current/parent pom properties
all those features mentioned above are very convenient from development perspective, however when you publish artifacts those features cause a pain in behind: that became not possible to use external library without it's parent pom, because parent pom may define dependencies and properties.
In your particular case someone have define version of parent pom as ${someVariable}, that in turn means it is not possible to use that library without information about the value of ${someVariable}. However, even if you had known the "correct" value of ${someVariable} and might specify it via system properties, that would cause some weird behaviour: today you may specify one value for ${someVariable}, tomorrow you (or someone else) will specify another value and ultimately you will get different builds, due to that maven denies such configurations (that is much better to fail a build rather than build something unreliable), that would be wiser to initially deny publishing such poms, but we have what we have.
It might be that the variable was stored in some user's settings.xml.
This would allow checking out an older version already in production for writing patches.
<settings>
...
<profiles>
<profile>
<id>work-in-progress</id>
<properties>
<someVariable>1.2.3</someVariable>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>work-in-progress</activeProfile>
</activeProfiles>
</settings>
So you might do that too. And search in users' directories, .m2 repo directories where usually the settings.xml is stored.

Setting the developerConnection for the Maven Release Plugin from the command line

I am currently trying to configure the Maven Release Plugin for our build server.
For that I am trying to set the <scm><developerConnection> through the command line. I read that
project.scm.developerConnection
is the command line property(https://maven.apache.org/guides/mini/guide-releasing.html). I tried to set it but it seems to have no effect. When I start the build, it uses a constructed URL (parent pom url + artifactId) that fails.
I have looked at the source code of the plugin but did not find the command line property mentioned above.
Can anybody shed light on this?
It looks that you cannot pass this property directly from command line. See:
https://issues.apache.org/jira/browse/MRELEASE-707
But you should get it working by specifying it through a custom property in your pom.xml:
<properties>
<my.developer.connection />
</properties>
<scm>
<developerConnection>${my.developer.connection}</developerConnection>
<tag>HEAD</tag>
</scm>
And running maven with, for example:
-Dmy.developer.connection=scm:git:ssh://user#host/repo.git
I use this approach to keep my pom.xml clean when generating a public release that should not contain information about my company's internals.
When you run mvn release:prepare, Maven forks. The arguments supplied on the command line are passed to the initial Maven call (the one you/build server ran) not to the fork.
To pass args to the release plugin, supply the arguments as shown:
mvn release:prepare -Darguments="-Dproject.scm.developerConnection=..." ...
Depending on what I'm trying to do, sometimes I've had to specify in two places, so both original and forked processes get the args:
mvn release:prepare -DsomeArg=val -Darguments="-DsomeArg=val" ...
The first example in the release plugin FAQ shows an example of where the latter is useful.
---- Update ----
I found the property in the maven-scm-plugin code.
Maybe project.scm.developerConnection is read-only? Try setting scmDeveloperConnection instead, as it's listed as the property name.

How to use maven run parameters in the maven project?

I am having a new Maven project and I want to pass parameters through command line..
This is my requirement -
If I pass - install -Dinfra=local then my test should run on local machine
If I pass - install -Dinfra=ip then my test should run on the machine having desired ip.
I just wanted to know how to configure this infra into my project so that I can access that through command line.. Many thanks!
You can define a property in your POM:
<project>
...
<properties>
<infra>local</infra>
</properties>
...
</project>
Then you can reference it in the POM by using ${infra}. You can overwrite the value of the property through the command line (as in your example).
Also see https://stackoverflow.com/a/13709976/927493

Maven: Define SuperPOM property project.build.directory over command line

I am building my maven project with GitLab CI on a docker file.
I would like to configure my pipeline with a "compile" stage and a "test" stage. To be able to do that, I need to set the property project.build.directory, which is defined in the maven super POM, to the docker cache so the compiled artefact does not get lost between the jobs.
project.build.directory is a predefined maven property. Therefore I would think that I am able define it with the CL parameter -Dproject.build.directory=anotherDir. This somehow does not work and my project still gets built to the default directory target.
If I modify my POM with
<properties>
<buildDir>target</buildDir>
</properties>
<build>
<directory>${buildDir}</directory>
</build>
and call mvn clean install -DbuildDir=customTargetDir, my project gets built to the customTargetDir as expected.
Why is that? I really don't see a difference. I both cases, I define the value of an existing property.

Change version of Maven project without manipulating the POM file

Is it somehow possible to change the version of a Maven project without manipulating the POM file?
Let's say I have a Maven project with version 1.5.0-SNAPSHOT but I want to build it as 1.5.46.
The Versions Maven Plugin unfortunately modifies the POM files.
Since Maven 3.5.0 this is possible using a special predefined property: ${revision}. Define the property with a default value (e.g. 1.5.0-SNAPSHOT) and when needed, set it during execution to a specific version (e.g. 1.5.46).
For example, define the following in your pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<name>Foo Module</name>
<version>${revision}</version>
...
<properties>
<revision>1.5.0-SNAPSHOT</revision>
</properties>
</project>
Build it using the default value:
mvn clean install
This will produce an artifact identified as org.example:foo:1.5.0-SNAPSHOT.
In order to build a specific version, set the revision property, for example:
mvn clean install -Drevision=1.5.46
This will produce an artifact identified as org.example:foo:1.5.46.
For further details, see the Maven CI Friendly Versions page.
Try to override project version with
mvn versions:set -DnewVersion=<version>
in your particular case:
mvn versions:set -DnewVersion=1.5.46
You can
Make a copy of your pom as temppom.xml
Replace the version in temppom.xml
Build with mvn -f temppom.xml.
Delete temppom.xml.
Maven supports delivery friendly versions, see https://issues.apache.org/jira/browse/MNG-5576 .
For more details I would suggest to talk with #khmarbaise
The plugin provides a goal to revert the changes made by it:
mvn versions:revert

Resources