<activeByDefault/> doesn't work when another profile triggered - maven

I have profiles look like this.
<profile>
<id>active-by-default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>${version.org.mongodb}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>java8</id>
<activation>
<jdk>(,1.8]</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<configuration>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
<lib>${java.home}/lib/jce.jar</lib>
<lib>${java.home}/lib/jsse.jar</lib>
</libs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>java9</id>
<activation>
<jdk>[1.9,)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<configuration>
<libs>
<lib>${java.home}/jmods/java.base.jmod</lib>
</libs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
Those two java- profiles are for ProGuard.
And I found the active-by-default profile doesn't work even with no profiles specified.
I found it works when I remove one of those java- profile which meets my current JDK version.
Is this intended?

Yes, this is the documented behaviour :
This profile will automatically be active for all builds unless another profile in the same POM is activated using one of the previously described methods. All profiles that are active by default are automatically deactivated when a profile in the POM is activated on the command line or through its activation config.
https://maven.apache.org/guides/introduction/introduction-to-profiles.html

Related

How to run maven from the project

I am trying to start the maven from the root folder (where the file pom.xml is located) of the project via the command line, but I get an error that the command "mvn install" was not found. If I run a maven through the directory where it is installed, then it cannot find the project. How to run maven from the project?
pom.xml
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<groupId>ru.evgeniyosipov.facshop</groupId>
<artifactId>facshop</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<name>facshop</name>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.exec.plugin.version>1.4.0</maven.exec.plugin.version>
<integration.container.id>glassfish4x</integration.container.id>
<glassfish.home>${glassfish.home.prefix}/glassfish4</glassfish.home>
</properties>
<profiles>
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<glassfish.home.prefix>c:/</glassfish.home.prefix>
<glassfish.executables.suffix>.bat</glassfish.executables.suffix>
</properties>
</profile>
<profile>
<id>unix</id>
<activation>
<os>
<family>unix</family>
</os>
</activation>
<properties>
<glassfish.home.prefix>${user.home}</glassfish.home.prefix>
<glassfish.executables.suffix />
</properties>
</profile>
</profiles>
<modules>
<module>facshop-events</module>
<module>facshop-entities</module>
<module>facshop-resources</module>
<module>facshop-payment</module>
<module>facshop-store</module>
<module>facshop-shipment</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.4.14</version>
<executions>
<execution>
<id>Deploy</id>
<phase>integration-test</phase>
<goals>
<goal>redeploy</goal>
</goals>
<configuration>
<container>
<containerId>${integration.container.id}</containerId>
<type>installed</type>
<home>${glassfish.home}</home>
</container>
<configuration>
<type>existing</type>
<home>${glassfish.home}/glassfish/domains</home>
<properties>
<cargo.glassfish.domain.name>domain1</cargo.glassfish.domain.name>
<cargo.glassfish.admin.port>4848</cargo.glassfish.admin.port>
<cargo.remote.username>admin</cargo.remote.username>
<cargo.remote.password></cargo.remote.password>
</properties>
</configuration>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
You need to add the maven bin directory to the PATH. Then you can call it from the project directory.

Pass JVM args to maven surefire, conditional on build Java version?

Is there a way that I can pass this argLine configuration to the maven-surefire plugin ONLY when <jdk.version>1.7</jdk.version> is configured for Java 1.7 but NOT when a user changes the pom.xml to be configured for java 1.8?
The reason being that Java 1.8 doesn't have permgen space.
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
You can use Maven profile activation based on properties value, in this case the property will be jdk.version and its value the different configuration of JDK. The profile will then change the Maven Surefire Plugin configuration accordingly.
Hence, your pom may look like the following:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>sample-project</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<jdk.version>1.7</jdk.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>surefire-java7</id>
<activation>
<property>
<name>jdk.version</name>
<value>1.7</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>surefire-java8</id>
<activation>
<property>
<name>jdk.version</name>
<value>1.8</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<argLine>-Xmx1024m</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Note the profiles section at the end. Two profiles are defined:
surefire-java7: it will be activated by the value 1.7 for the jdk.version variable and set the argLine for the Maven Surefire Plugin with the desired value
surefire-java8: it will be activated by the value 1.8 for the jdk.version variable and set a different argLine for the Maven Surefire Plugin.
Also note that with this configuration you can even switch JDK version (and as such Surefire configuration) at demand from the command line, as following:
mvn clean test -Djdk.version=1.8
The associated profile will be automatically activated as part of the build.
Important note about cross-compilation (you may already be aware of it, but just in case) I would suggest to carefully read this question/answer.
Rather than a property, you should use the JDK based activation.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<artifactId>sample-project</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<jdk.version>1.7</jdk.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>surefire-java7</id>
<activation>
<jdk>(,1.8)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>surefire-java8</id>
<activation>
<jdk>1.8</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<argLine>-Xmx1024m</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Cf maven documentation.
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html

Maven profile not deploying to correct tomcat using maven-tomcat-plugin

So my Maven doesn't want to pickup the right profile, doesn't matter how I tell it:
mvn -Denv=dev tomcat7:deploy-only or mvn -P dev -Denv=dev tomcat7:deploy-only
I have two servers configured on my settings.xml and have my configuration below pointing to the correct ones.
Using mvn -X it seems that Maven is always picking up the last server in order it appears on the file, which means it's picking up the prod server.
Any clues anyone? Thank you!
Here's my <profiles>:
<profiles>
<profile>
<id>dev</id>
<activation>
<property>
<name>env</name>
<value>dev</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0-beta-1</version>
<configuration>
<server>dev</server>
<url>http://localhost:8080/manager/text</url>
<username>tomcat</username>
<password>tomcat</password>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>prod</id>
<activation>
<property>
<name>env</name>
<value>prod</value>
</property>
<jdk>1.6</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0-beta-1</version>
<configuration>
<server>prod</server>
<url>http://remote/manager/text</url>
<username>usr</username>
<password>pwd</password>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
You have an extra "activation" of <jdk>1.6</jdk> in your prod profile. Activations are an "or", not an "and". I'm guessing you're running maven with jdk6, and so prod is always active. Being the last one in the pom, its settings will win--a general rule in maven.

How to run the exec-maven-plugin if a system property id set in Maven 3.x?

I want to run the 'exec-maven-plugin' if a system property is set. How do I accomplish this in Maven 3.x?
For example, given:
mvn clean install -DrunTheExec="yes"
Then how can I implement this logic:
<!-- if $(runTheExec) == yes then run this plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
...
</plugin>
I was just about to add the same suggestion as Johnathon, but using the profile a little differently.
<profiles>
<profile>
<id>runTheExec</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
...
then to activate it:
mvn clean install -PrunTheExec
You'll need to define a profile in your pom, with the plugin defined inside of it. In your example, this would be:
<profiles>
<profile>
<activation>
<property>
<name>runTheExec</name>
<value>yes</value>
</property>
</activation>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
...
</plugin>
</plugins>
</profile>
</profiles>

In maven - how to rename the output .war file based on the name of the profile in use

I have three profiles in my pom.xml for our application...
dev (for use on a developer's)
qa (for use on our internal qa server)
prod (production).
When we run our maven build all three profiles ouput a war file with the same name. I would like to output $profilename-somearbitraryname.war
Any ideas?
You've answered yourself correctly:
<profiles>
<profile>
<id>dev</id>
<properties>
<rp.build.warname>dev</rp.build.warname>
</properties>
</profile>
<profile>
<id>qa</id>
<properties>
<rp.build.warname>qa</rp.build.warname>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<rp.build.warname>prod</rp.build.warname>
</properties>
</profile>
</profiles>
but there is a simpler way to redefine WAR name:
<build>
<finalName>${rp.build.warname}-somearbitraryname</finalName>
<!-- ... -->
</build>
No maven-war-plugin is needed.
The answer was simple...
Define a property in each profile like this...
<profile>
<id>qa</id>
<properties>
<rp.build.warname>ourapp-qa</rp.build.warname>
</properties>
</profile>
Then add this to your plugins...
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<packagingExcludes>WEB-INF/web.xml</packagingExcludes>
<warName>${rp.build.warname}</warName>
</configuration>
</plugin>
In maven you must use <bundleFileName> in the <module>
You should follow this link to ensure your modules are rewritted:
http://maven.apache.org/plugins/maven-ear-plugin/examples/customizing-a-module-filename.html
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10.1</version>
<configuration>
[...]
<modules>
<ejbModule>
<groupId>artifactGroupId</groupId>
<artifactId>artifactId</artifactId>
<bundleFileName>anotherName-1.2.3.jar</bundleFileName>
</ejbModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>

Resources