Maven property overloading - maven-2

I have very simple maven descriptor which defined some properties:
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<properties>
<it.port>8080</it.port>
</properties>
</project>
I can override it.port property with command:
$ mvn -Dit.port=8181 verify
But following command doesn't work as expected:
$ MAVEN_OPTS="-Dit.port=8181" mvn verify
This pass system variable to the JVM but maven refuse to override this property and default value given to test (8080). Original problem is that TeamCity (out CI server) pass system variables to the JVM in MAVEN_OPTS, so property overriding doesn't work.
Can I override maven properties with MAVEN_OPTS environment variable?

No you can't. You can:
Use settings.xml on your local machine to specify the property
Use a profile in the project pom
Use -D directly on the command line.

Related

Maven - How to pass partial value in system property variables from POM.xml

here below is my url variable in pom.xml where i have to append qa value in ${evn} to run in different environment,
i want to pass env alone from my url tag to pass on run time like below
mvn clean test -Denv=qa
my expectation to get url in test is like - https://www.qagoogle.com
<systemPropertyVariables>
<url>https://www.${env}google.com/</url>
</systemPropertyVariables>
If you want to override the variable with -Denv you also need to add it to systemPropertyVariables
<systemPropertyVariables>
<env></env>
<url>https://www.${env}google.com/</url>
</systemPropertyVariables>
and then, you can run mvn clean test -Denv=qa
You need to add a properties section to your pom.xml:
<properties>
<env>qa</env>
</properties>

What is the difference between these Kotlin compiler flags?

For some time Kotlin allowed to set kotlin.incremental=true and since 1.1.2 there is also kotlin.compiler.incremental=true.
I would like to know what is the difference between these two?
According to Alexey Tsvetkov kotlin.compiler.incremental is maven only, and it is named similar to other maven options.
kotlin.compiler.incremental is a property, which can be set in a maven project to enable incremental kotlin compilation by default.
It is set in the properties block in pom.xml:
<project>
...
<properties>
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
</properties>
...
</project>
Or you can pass this option with the command line argument:
mvn install -Dkotlin.compiler.incremental=true
It is all about maven build logic. Look here for more details: Maven Incremental Build

Debug Maven to find out the war file name that has been created

I am getting this exception in Maven2 when i run mvn deploy
Please see the error
[INFO] An Ant BuildException has occured: Warning: Could not find file D:\bayer\service\target\${file.name}.war to copy.
I have this below line under my POM.xml file
Please tell me is it possible to see the file.name that is forming at runtime ??
I have this line under my POM.xml file
<copy file="${project.build.directory}/${file.name}.${project.packaging}" tofile="${deploy.home}/${webapps.dir}/${file.name}.${project.packaging}" />
How can we debug this ??
By default maven generated wars will have the following name:
${artifactId}-${version}.war
In you antrun plugin you can reference maven properties ( see http://maven.apache.org/plugins/maven-antrun-plugin/usage.html ).
So if you replace file.name property by a direct maven reference it will just work:
${project.build.directory}/${artifactId}-${version}.${project.packaging}
( above assumes that your ant script is inside the pom.xml and not externalized )
You also can override that in the build section of your pom.xml:
<build>
<finalName>MySuperCoolApplication</finalName>
...
</build>
For general debug output from mvn just use the -X flag

deploying a versioned WAR file to tomcat

I was wondering what would be the best practice to deploy a maven packaged WAR file to tomcat.
Using maven release plugin I get a versioned war file for my project
eg: myservice-1.0.0.war
I would like to deploy it to tomcat so that I can access it as follows
eg: http://localhost:8080/myservice
By default tomcat explodes the war file as a directory with a name myservice-1.0.0 under CATALINA_HOME/webapps. But I want to to explode the war as a directory with a name myservice for the reasons mentioned above.
I know I can simply rename myservice-1.0.0.war >> myservice.war and then deploy it in Tomcat.
I wanted to find out what others do?
I would do it by mentioning myservice as artifactId and final name and using maven cargo plugin to deploy to tomcat.
http://cargo.codehaus.org/Maven2+Plugin+Tips
You can package file /META-INF/context.xml with content like this:
<?xml version="1.0"?>
<!DOCTYPE Context>
<Context path="myapp">
</Context>
See documentation at http://tomcat.apache.org/tomcat-5.5-doc/config/context.html
I ran into the same problem. What worked for me was inserting this properties element into the cargo deployable configuration:
<deployable>
<groupId>org.something</groupId>
<artifactId>something-idm-esb</artifactId>
<properties>
<context>something-idm-esb</context>
</properties>
<type>war</type>
</deployable>
Without this properties element, the app would be deployed to localhost:8080/something-idm-esb-0.9.14.2 which is not what the app needs at runtime. With the properties section, the app is deployed to localhost:8080/something-idm-esb/
Instead of renaming the war file you could do this:
Just add following in your tomcat-dir/conf/server.xml in between <Host>..<\Host> tags.
for : myservice-1.0.0.war file
<Context path="/myservice" docBase="/myservice-1.0.0" debug="0" reloadable="true"></Context>
Reference

How can maven be used in a continuous integration situation to install versioned artifacts in the repository?

We are in the process of converting our main build process from ant to maven. We use TeamCity for our Continuous Integration server (CI).
We'd like to use the CI server to kick off (nightly) builds whose version contain a build number, as in 1.0.0.build#. These builds would be installed in our local maven repository to be used by other projects. So the CI server would manage the versions, maven would build the project, and the maven repository would make the builds accessible to other projects.
I intended to initiate the build from the CI server using the following command:
mvn -Dversion=1.0.0.25 install
The project's pom would have a bogus version number, and the -D flag would override it, as in:
<version>0.0.0.0</version>
The problem with this method is that the maven install plugin only uses the version in the pom file, not the version passed in on the command line. This is noted in this maven issue.
So since this issue has existed since 08/2006 and has not been fixed, I assume that this is somehow not 'the maven way'. So my question is, how can maven be used in a continuous integration situation to install versioned artifacts in the repository?
Sounds like you want to build SNAPSHOT versions with unique versions.
So, in your POM declare the version as:
<version>#.#.#-SNAPSHOT</version>
Then, in the distributionManagement section of your POM, enable unique versions for the snapshotRepository via (see Maven's POM reference on this):
<snapshotRepository>
<uniqueVersion>true</uniqueVersion>
<id>your-snapshot-repo-id</id>
<name>Your Snapshots</name>
<url>http://your-snapshot-repo-url/maven</url>
</snapshotRepository>
FYI, note that Maven conventions recommend versions be declared as major.minor.revision. So, 1.0.25 instead of 1.0.0.25. If you're able to use this versioning scheme, things will work more smoothly in a Maven world.
Matthew's answer provides a solution where the artifacts get uploaded into the local and remote repository having the desired version number, i.e. the paths inside the repository are contain the correct version numbers, however, Maven installs and deploys always the source POM file that would still contain the ${ciVersion} in the version element.
If you have a multi-module with a common parent like this:
<project xmlns="..." xmlns:xsi="..." xsi:schemaLocation="...">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>myParent</artifactId>
<groupId>com.stackoverflow</groupId>
<version>${ciVersion}</version>
</parent>
<artifactId>myChild</artifactId>
...
</project>
you won't be able to reference a dedicated version of the myChild module, as the dependency resolution will exist with an error that it cannot find the myParent module with version ${ciVersion}.
However, you could use the resolve-pom-maven-plugin that uploads a POM into the local and remote repository where all variables inside the POM get substituted by their actual values. In order to do this, you have to add the following snippet into your (parent) POM:
...
<build>
<plugins>
<plugin>
<groupId>com.sap.prd.mobile.ios.maven.plugins</groupId>
<artifactId>resolve-pom-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>resolve-pom-props</id>
<goals>
<goal>resolve-pom-props</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
Shek's answer is probably 'the maven way', so I'll accept it as the correct answer. However, we are not ready to change our conventions, so here is the workaround that we are using.
By using a level of indirection you can pass a version number in to the pom at build time and have the install and deploy plugins use them. For example:
<project xmlns="..." xmlns:xsi="..." xsi:schemaLocation="...">
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>stackoverflow</artifactId>
<version>${ciVersion}</version>
<packaging>jar</packaging>
<name>StackOverflow</name>
<properties>
<ciVersion>0.0.0.0</ciVersion>
</properties>
...
</project>
We cannot override ${project.version} directly. So instead, we add a second property called 'ciVersion' and give it a default value of '0.0.0.0' in the properties section. Now the CI server can specify a version number by overriding the ciVersion property on the command line. As in:
mvn -DciVersion=1.0.0.25 install
The install and deploy plugins will use the value of the ciVersion property that was passed in whenever ${project.version} is referenced, as expected, and the default value will be used when no version is provided on the command line. This allows us to switch to maven with minimal impact on our process. In addition, this workaround is unobtrusive, allowing for an easy switch to the SNAPSHOT functionality when desired.