How to "put" maven command line in pom.xml? - maven

How can I "put" a command line parameter to be executed from pom.xml.
For example I have:
mvn clean install -Dmyparameter
And I wish It to be executed from pom.xml instead from command line.

It depends on which phase you need to use the args. It can be done on plugins by changing the configuration parameter.
<pluginManagement>
<plugin>
......
......
<artifactId>maven-release-plugin</artifactId>
<configuration>
<arguments>-Dmaven.test.skip=true -D[other arguments that u need to include]</arguments>
</configuration>
......
......
</plugin> </pluginManagement>
Same way in the sure fire plugin u can skip test and so on!!

You can try to use maven-exec-plugin:
mvn clean install exec:exec -Dexecutable=<absolute path to binary>
Also it can be bound to some phase of lifecycle to be executed in the middle of the build (without explicit call by exec:exec) and defined in profile with activation if property exists to run optionally:
<profiles>
<profile>
<id>exec</id>
<activation>
<property>
<name>executable</name>
</property>
</activation>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>exec</id>
<goals>
<goal>exec</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<executable>${executable}</executable>
</configuration>
</plugin>
</plugins>
</profile>
</profiles>

Related

injecting new argument/property value to maven profile in module

i have main pom.xml
i like to change from the main mvn command line cli which I'm using and change the :
<argument>${docker.image}</argument>
argument in only in the submodule :
module_y profile NOT module_x
this is the command I'm executing now :
mvn clean install -Ddocker_build=build
<artifactId>foo</artifactId>
<version>b1</version>
<packaging>pom</packaging>
<properties>
<docker.image>www.repo.org:8000/${project.artifactId}:${project.version}</docker.image>
</properties>
<modules>
<module>module_x</module>
<module>module_y</module>
</modules>
this is the section in the module_x and module_y
<profiles>
<profile>
<activation>
<property>
<name>docker_build</name>
<value>build</value>
</property>
<file>
<exists>Dockerfile</exists>
</file>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<phase>install</phase>
<configuration>
<executable>docker</executable>
<arguments>
<argument>build</argument>
<argument>-f</argument>
<argument>${project.basedir}/Dockerfile</argument>
<argument>-t</argument>
<argument>${docker.image}</argument>
<argument>.</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
in short, how do i change only the property value ${docker.image} in profile docker_build in module_y from main mvn run?
If you cannot change the POMs, this cannot be done.
The only possible approach would be to build the modules separately (by using -pl module_x -am or something like that) and use different command line parameters in both cases.

Pass "non D" parameter to jenkins maven build step

I have a couple of "Invoke top-level Maven targets" build steps in a project being build by Jenkins.
In the "Properties" field you can specify an arbitray amount of maven build parameters like
skipTests=true evaluating to -DskipTests=true
However I want to pass a build parameter that must not be preceded by -D and also does not require an equals sign.
Like -Psomething.
Is there any way to do this using the "Invoke top-level Maven targets" or do I need to trigger the mvn build manually via "Execute shell"?
Thanks!
A workaround to passing properties is to set environment variables and read them. See this SO post.
Another workaround is by using a profile. Basically in following example you will have to set environment variable RUNTESTS to true to activate your profile and you can do the intended tasks inside this profile (e.g. running junits conditionally.):
<profile>
<id>runtests</id>
<activation>
<property>
<name>env.RUNTESTS</name>
<value>true</value>
</property>
</activation>
<build>
<finalName>re</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M1</version>
<configuration>
<executions>
<execution>
<id>default-test</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
<testFailureIgnore>false</testFailureIgnore>
</configuration>
</plugin>
</plugins>
</build>
</profile>

Maven: How to print the current profile on the console?

I'm trying to print the current profile that is active running a build of a Maven Project.
I'm using the maven-antrun-plugin in order to print messages on the console, in combination with a property that refers to the current profile.
I have tried the following properties:
${project.activeProfiles[0].id}
${project.profiles[0].id}
But in both cases it prints the "string" as it is written, without resolving the variable.
This is my test:
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>current active profile: ${project.activeProfiles[0].id}</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
But this is the result that I obtain:
main:
[echo] current active profile: ${project.activeProfiles[0].id}
Any suggestion will be appreciated.
Thanks.
The maven-help-plugin offers what you need. It has an active-profiles goal.
You can add it to your pom or even call it from the command line (include it in your maven build call). The How can I tell which profiles are in effect during a build? section of the Maven profile introduction page will show you how. In short:
mvn help:active-profiles
As this does not work for you (see comments) here is another solution:
I think the active profiles (there can be more than one!) are not propagated as available variables - but properties are.
So set a custom property in the profile section and use that, like
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<myProfile>default</myProfile>
</properties>
</profile>
<profile>
<id>debug</id>
<activation>
<property>
<name>debug</name>
</property>
</activation>
<properties>
<myProfile>debug</myProfile>
</properties>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo>current active profile: ${myProfile}</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
you can add the maven-help-plugin in your pom to display always the active profile
<build>
<plugins>
<!-- display active profile in compile phase -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>show-profiles</id>
<phase>compile</phase>
<goals>
<goal>active-profiles</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
source: https://www.mkyong.com/maven/maven-profiles-example

Maven - skip plugin if property is empty/null

I want to obtain the following behavior: when I specify a value for the property "my.prop", I want the dependency and clean plugins to be executed. If a value is not specified for that property, I want them to be skipped.
I created "my.prop" like this:
<properties>
<my.prop></my.prop>
</properties>
Then I read that profile activation works only for system properties, so I deleted the above and used the surefire plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<systemPropertyVariables>
<my.prop></my.prop>
</systemPropertyVariables>
</configuration>
</plugin>
I tried using profiles, like this:
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<skipDependecyAndCleanPlugins>false</skipDependecyAndCleanPlugins>
</properties>
</profile>
<profile>
<id>skip-dependency-and-clean-plugins</id>
<activation>
<property>
<name>my.prop</name>
<value></value>
<!-- I also tried: <value>null</value> without success.-->
</property>
</activation>
<properties>
<skipDependecyAndCleanPlugins>true</skipDependecyAndCleanPlugins>
</properties>
</profile>
</profiles>
Later, for each plugin I do something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<configuration>
<skip>${skipDependecyAndCleanPlugins}</skip>
</configuration>
....
</plugin>
But the plugins are still executed...
How can I determine Maven to skip the executions of the plugins when "my.prop" is empty/null?
The simplest solution would be to use the activation in the following form:
<profiles>
<profile>
<activation>
<property>
<name>debug</name>
</property>
</activation>
...
</profile>
</profiles>
The above means you can define any value for debug which means -Ddebug is enough.
An empty value can't be defined a pom file cause <value></value> is equivalent to <value/> which means the same as not defined.
Update:
I would suggest to use a profile and NOT a property. So you can simply define on command line mvn -Pxyz install or leave it.
You can use my.prop property in plugin's configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<configuration>
<skip>${my.prop}</skip>
</configuration>
....
</plugin>
Now when you execute:
mvn ... -Dmy.prop=true
then plugin will be skipped
You were very close. You can achieve what you described by using the !my.prop syntax in profile activation.
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<configuration>
<skip>${skipDependecyAndCleanPlugins}</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>skip-dependency-and-clean-plugins</id>
<activation>
<property>
<name>!my.prop</name>
</property>
</activation>
<properties>
<skipDependecyAndCleanPlugins>true</skipDependecyAndCleanPlugins>
</properties>
</profile>
</profiles>
According to Maven documentation, the skip-dependency-and-clean-plugins profile will be activated when the system property my.prop is not defined at all.
Here is a solution that directly addresses the OP's original request: the ability to skip a plugin's execution if a POM property (not a system property) my.prop is not defined. This solution relies on the Apache Maven Help Plugin. It is a kludge, but given Maven's paucity of expression prowess, this is about the best you're gonna get. At least it relies on a well-known, hopefully-maintained plugin, and should work 100% of the time. Oh, and it may make your head explode. Or make you cry. Or both. You've been warned.
First declare the latest version of the Maven Help Plugin in the <build><pluginManagement> section:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.3.0</version>
</plugin>
Then add this "secret sauce" in the <build><plugins> section, which will check to see if my.prop is defined:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>set-is-skip-true-or-prefixed</id>
<phase>validate</phase>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>is-skip</name>
<value>_${my.prop}</value>
<regex>_\$\{my.prop\}</regex>
<replacement>true</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
<execution>
<id>set-is-skip</id>
<phase>initialize</phase>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>is-skip</name>
<value>${is-skip}</value>
<regex>_.*</regex>
<replacement>false</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
Now you have a POM property (not a system property) named is-skip, which you can use in any later phase to disable a plugin—provided that plugin has a <skip> or similar option taking a Boolean value. If my.prop is not defined at all, is-skip will be set to true; otherwise is-skip will be set to false.
<plugin>
<groupId>org.example</groupId>
<artifactId>foobar-plugin</artifactId>
<executions>
<execution>
<id>foo</id>
<phase>package</phase>
<goals>
<goal>foo</goal>
</goals>
<configuration>
<skip>${is-skip}</skip>
</configuration>
</execution>
</executions>
</plugin>
There is one caveat: don't define my.prop at all, even to the empty string, or this solution will consider it defined and set is-skip to false. Setting is-skip to true if my.prop is set but empty would require an additional regex evaluation clause above. For my use case I didn't need it, as an empty my.prop isn't valid and I didn't define my.prop at all in the parent POM.
I'll leave it to you to understand how it works (my head exploded already when I was writing it), but I'll be happy to answer any questions.
In step #2 above, be sure and put the two regex evaluations in different phases, such as validate and initialize as used here. The reason is because Maven gets confused if you mix in the same plugins in in the same phase a child POM, and may scramble the execution order. (See MNG-5987.) My kludge of a solution relies on the order of evaluation.

maven calls external script on both Linux and Windows platforms

I need to run an external script on both Linux and MS-Windows platforms.
Do I use the right plugin exec-maven-plugin?
Is there a more suitable plugin?
What filename should I put in <executable>....</executable>?
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>compile-jni</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>./compile-jni</executable>
<workingDirectory>${basedir}/src/main/cpp</workingDirectory>
</configuration>
</execution>
</executions>
</plugin>
I use the same Makefile for both platforms Linux/MS-Windows
My script compile-jni.bat:
call "%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
bash -c "make"
My script compile-jni.sh:
#!/bin/sh
make
UPDATE:
Two colleagues have suggested alternatives:
Use a variable script.extension
change <executable>./compile-jni${script.extension}</executable> in the pom.xml
and append the variable within the command line mvn compile -Dscript.extention=.bat
or set the Visual Studio environment variables before calling maven:
call "C:\%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
mvn compile #(the same script 'bash -c "make"' works on both platforms)
But on both solutions, Eclipse users may be stucked... I am still looking for an automatic and elegant solution...
Finally, I mixed the ideas => the <profiles> are used to set an internal variable script.extension depending on the operating system:
<profiles>
<profile>
<id>Windows</id>
<activation>
<os>
<family>Windows</family>
</os>
</activation>
<properties>
<script.extension>.bat</script.extension>
</properties>
</profile>
<profile>
<id>unix</id>
<activation>
<os>
<family>unix</family>
</os>
</activation>
<properties>
<script.extension>.sh</script.extension>
</properties>
</profile>
</profiles>
Then I use the variable to complete the script filename:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>compile-jni</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>./compile-jni${script.extension}</executable>
</configuration>
</execution>
</executions>
</plugin>
⚠ As noticed by Maksim for maven 3.5.4 move up the section <configuration> as shown below:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<executable>./compile-jni${script.extension}</executable>
</configuration>
<version>1.2.1</version>
<executions>
<execution>
<id>compile-jni</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
I have moved the working directory from the pom.xml to the shell script. In order to simplify maintenance, the common stuff is moved within this shell scrip. Therefore, the batch file use this shell script:
compile-jni.bat:
call "%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
bash compile-jni.sh
compile-jni.sh:
#!/bin/sh
cd src/main/cpp
make
An example of running sh script.
This just does a chmod for the sh script. Keep in mind if you have a sh script, you should definitely do a chmod before performing other operations such as running the actual script, so having this as an example, you can do the first <execution> as below and add another <execution> to run your script.
For the batch file, you can have only one <execution> to run your script
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${org.codehaus.mojo.version}</version>
<executions>
<execution>
<id>script-chmod</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>chmod</executable>
<arguments>
<argument>+x</argument>
<argument>yourscript.sh</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
and you would probably want to add a profile depending on which machine you are:
<profiles>
<profile>
<activation>
<os>
<family>!windows</family>
</os>
</activation>
<plugin>
<!-- add your exec-maven-plugin here -->
</plugin>
...
</profile>
</profiles>
Hope this will be a start for what you need

Resources