I have a Maven pom.xml with a plugin that I want to be able to control on the command line. Everything works otherwise fine, except even after searching the net a while I can't figure out how to set a default value for my control property:
<plugin>
...
<configuration>
<param>${myProperty}</param>
</configuration>
...
</plugin>
So if I run Maven with
mvn -DmyProperty=something ...
everything's fine, but I'd like to have a specific value assigned to myProperty also without the -DmyProperty=... switch. How can this be done?
You can have the property default value defined in <build>/<properties> or in a profile like shown below. When you supply the property value on command line with -DmyProperty=anotherValue then it will override the definition from the POM. That is, all definitions of property values in the POM are set only a default value for the properties.
<profile>
...
<properties>
<myProperty>defaultValue</myProperty>
</properties>
...
<configuration>
<param>${myProperty}</param>
</configuration>
...
</profile>
Taylor L's approach works fine, but you don't need the extra profile. You can just declare property values in the POM file.
<project>
...
<properties>
<!-- Sets the location that Apache Cargo will use to install containers when they are downloaded.
Executions of the plug-in should append the container name and version to this path.
E.g. apache-tomcat-5.5.20 -->
<cargo.container.install.dir>${user.home}/.m2/cargo/containers</cargo.container.install.dir>
</properties>
</project>
You can also set properties in your user settings.xml file in the event that you want each user to be able to set their own defaults. We use this approach to hide credentials that the CI server uses for some plug-ins from regular developers.
You could use something like below:
<profile>
<id>default</id>
<properties>
<env>default</env>
<myProperty>someValue</myProperty>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
#akostadinov's solution works great for common usage... But if the desired property shall be used by reactor component during dependency resolution phase (very early in mvn pom hierarchy processing...) you should use profile "none activation" test mechanism to ensure the optional command line provided value is always prioritized regarding the value provided inside pom.xml. And this whatever deep is your pom hierarchy.
To do so, add this kind of profile in your parent pom.xml :
<profiles>
<profile>
<id>my.property</id>
<activation>
<property>
<name>!my.property</name>
</property>
</activation>
<properties>
<my.property>${an.other.property} or a_static_value</my.property>
</properties>
</profile>
</profiles>
This might work for you:
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugin>
<configuration>
<param>Foo</param>
</configuration>
</plugin>
</build>
...
</profile>
<profile>
<id>notdefault</id>
...
<build>
<plugin>
<configuration>
<param>${myProperty}</param>
</configuration>
</plugin>
</build>
...
</profile>
</profiles>
That way,
mvn clean will use "foo" as your default param. In cases when you need to override, use mvn -P notdefault -DmyProperty=something
I took sal's approach but flatten it a bit.
<profiles>
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugin>
<configuration>
<version>LATEST</version>
</configuration>
</plugin>
</build>
</profile>
</profiles>
Now you have 2 options:
Using default value: MVN install (all $version will be replaced with LATEST)
Using own value: MVN install -P! Default -Dversion=0.9 (all $version will be 0.9)
Related
The Maven Compiler Plugin compile goal indicates (as many of you already know) that I can turn off debug information by setting <debug>false</debug>.
<project …>
…
<profiles>
<profile>
<id>production</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<debug>false</debug>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
I note however that the same documentation indicates that the "user property" for this setting is maven.compiler.debug. What does it mean that something is a "user property"? Does this mean that I can simply set the maven.compiler.debug property to false in my profile, and not even mention anything about a plugin, like this?
<project …>
…
<profiles>
<profile>
<id>production</id>
<properties>
<maven.compiler.debug>false</maven.compiler.debug>
</properties>
</profile>
</profiles>
</project>
As answered in another question:
"User property" specifies the name of the Maven property that can be used to set a plugin parameter. This allows configuring a plugin from outside the section. Note that this only works if the parameter is not specified in the section (see MNG-4979 - Cannot override configuration parameter from command line).
The "User property" on Maven3 can be used on the command line, by specifying
-Dmaven.compiler.debug=false or
in a POM profile like example below, as per your question:
<properties>
<maven.compiler.debug>false</maven.compiler.debug>
</properties>
I am trying to set up a .pom file that will use one plugin if forkCount is 0, and a different plugin otherwise. Furthermore, I want 0 to be the default value. In other words, I want
mvn run_tests and mvn -DforkCount=0 run_tests to both use plugin "A", where mvn run_tests -DforkCount=5 will use plugin "B".
I have a .pom file with the following segments:
<project ...>
...
<properties>
<forkCount>0</forkCount>
</properties>
...
<profiles>
<profile>
<!-- if forkCount==0, don't invoke any of the parallel execution configuration -->
<id>no-parallel-execution</id>
<activation>
<property>
<name>forkCount</name>
<value>0</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<! --- nothing in here references forkCount -->
</plugin>
</plugins>
</build>
</profile>
<profile>
<profile>
<!-- forkCount!=0, use the parallel execution configuration -->
<id>parallel-execution</id>
<activation>
<property>
<name>forkCount</name>
<value>!0</value>
</property>
</activation>
<build>
<plugins>
<plugin>
...
<configuration>
...
<forkCount>${forkCount}</forkCount>
...
</configuration>
</plugin>
</plugins>
</build>
...
The only references to forkCount are included in above.
Everything works as expected if I pass a value for forkCount on the command line (i.e., plugin "A" is used when forkCount is 0; and plugin "B" is used otherwise). However, if I run mvn run_tests, then plugin "B" gets activated, even though ${forkCount} has a value of 0. What's going on?
For what it's worth:
>mvn -DforkCount=0 clean verify help:active-profiles
The following profiles are active:
- no-parallel-execution (source: ....
>mvn clean verify help:active-profiles
The following profiles are active:
- parallel-execution (source: ....
try
mvn -DforkCount=0 help:active-profiles
to verify that the profiles you really want to be active are active (and the ones you really don't want to be active are not).
-- updating answer to accommodate new information --
Thanks for the updates to the answer, the problem seems pretty clear now.
I believe the issue is that "" is not "0". With this understanding, this means that "!0" is going to activate on a '' or missing forkCount value.
My tests confirm this interpretation.
Perhaps you can redo this, using more profiles. One to detect the condition of the property not being set, and one to detect the conditions of the property being zero. Both of these profiles might leave an artifact, say a touched file in the $target directory. Then you might use this file to know you are doing a single-threaded call, and without the file, a multi-threaded call.
Code used to confirm these ideas
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>edwinbuck.com</groupId>
<artifactId>example-properties</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<profiles>
<profile>
<id>unspecified-forkCount</id>
<activation>
<property>
<name>!forkCount</name>
</property>
</activation>
</profile>
<profile>
<id>zero-forkCount</id>
<activation>
<property>
<name>forkCount</name>
<value>0</value>
</property>
</activation>
</profile>
<profile>
<id>parallel-execution</id>
<activation>
<property>
<name>forkCount</name>
<value>!0</value>
</property>
</activation>
</profile>
</profiles>
</project>
command line calls used to confirm these ideas
mvn help:active-profiles
mvn -DforkCount=0 help:active-profiles
mvn -DforkCount=3 help:active-profiles
results
profiles: unspecified-forkCount parallel-execution
profiles: zero-forkCount
profiles: parallel-execution
Little stuck here. I have a pom with 3 profiles. Theese profiles have different version name. I want to inject that version name into properties file when a specific profile is building.
My profiles:
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<projectVersion>DEV</projectVersion>
</properties>
</profile>
<profile>
<id>test</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<projectVersion>1.0.0-RC1</projectVersion>
</properties>
</profile>
<profile>
<id>prod</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<projectVersion>1.0.0-Final</projectVersion>
</properties>
</profile>
</profiles>
and filter.properties looks like this:
projectName = defaultName
versionName = defaultVersion
How to do that? Im building project by command:
mvn clean install -D profile_name
What you need to do is to add a new section to your <build> section of your POM file.
Like this:
<build>
<resources>
<resource>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
This will look inside the specified folder (src/main/resources) on the specified files **/*.properties and change the files when it encounters defined variables.
So in order to this work your propertie file must be this way:
projectName = ${defaultName}
versionName = ${defaultVersion}
Be aware with these variables name. Maven will replace it with the defined names by you or the names of the Maven structure like ${projectVersion} will be replaced by the <version>1.0</version> tag of your pom file.
So instead of using:
<properties>
<projectVersion>1.0.0-Final</projectVersion>
</properties>
Change the name (and the version) of this variable to something else like:
<properties>
<defaultVersion>1.0.0-Final</defaultVersion>
<defaultName>someName</defaultName>
</properties>
On all your profiles.
And just run your maven command as:
mvn install -Pprofilename
Be careful with the profiles you shown. All of them are active by default and this is a problem because they all define the same maven property. Instead, you should mark only one as active by default.
You also don't show <resources> filtering to process filter.properties, so this can be a mistake, as well.
And a final though, you are controlling artifact version on maven profiles. I don't think it is a good idea. Please read about maven-release-plugin.
I'm using the maven-war plugin. I've also looked at the maven-versions plugin. In neither case do I see how to give a different name to a snapshot build than a release build.
I've seen examples using profiles but the docs seem to indicate that the use of profiles in the pom.xml is not a good idea.
How should this be done?
Try the below
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>src\main\webapp\WEB-INF\web.xml</webXml>
<classifier>${envClassifier}</classifier>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>snapshot</id>
<properties>
<envClassifier>snapshot</envClassifier>
</properties>
</profile>
<profile>
<id>release</id>
<properties>
<envClassifier>release</envClassifier>
</properties>
</profile>
</profiles>
Now, run command mvn clean install -Psnapshot Or mvn clean install -Prelease to get your desired artifacts. Hope this helps
You can control final war file name by warName attribute
We have a maven based Spring Web-Application. All the web-calls are Restful and need authentication. But for development purpose, it is a pain to do all the needful. So for the development cycle, it is preferred to not have any security.
Using a maven flag or something, how do we generate separate builds for production and development?
All the security related stuff are in web.xml and applicationContext.xml. We can have 2 copies (one for development and the other for production). In the maven build, what is the simplest way to include the necessary files and omit others.
PS: I have seen examples of doing above using assembly plugin. I do not need all that but just a simple way to do it. I am using maven-war-plugin to generate war file.
Use profiles. You define them in your pom.xml (see below) and then when you build you include them. For command line this is simply
mvn -P <profile> <target>
most IDE's provide a way to set a profile.
pom.xml:
<properties>
<!-- default -->
<webXmlPath>src\main\webapp\WEB-INF\web-test.xml</webXmlPath>
</properties>
<profiles>
<profile>
<id>Production</id>
<properties>
<webXmlPath>src\main\webapp\WEB-INF\web.xml</webXmlPath>
</properties>
<build>
<finalName>${artifactId}</finalName>
</build>
</profile>
<profile>
<id>Accept</id>
<properties>
<webXmlPath>src\main\webapp\WEB-INF\web-accept.xml</webXmlPath>
</properties>
<build>
<finalName>${artifactId}-accept</finalName>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webXml>${webXmlPath}</webXml>
</configuration>
</plugin>
</plugins>
</build>