Disable maven plugins when using a specific profile - maven

I'm looking to find a way of disabling a plugin execution if running with a particular profile.
This is the opposite of running a plugin if a profile is selected.
My use case: My Maven build has a whole load of plugins, but when running on my dev machine, I want to skip some of them. Instead of commenting those plugins out locally, I want to be able just run the build with a "dev" profile. The plugins would continue to run on my continuous build.
Ideas?

There is a neat way to disable plugin execution when specific profile is active.
Firstly you need to add an identifier to plugin execution like:
<build>
<plugins>
<!-- (...) -->
<plugin>
<groupId>nl.geodienstencentrum.maven</groupId>
<artifactId>sass-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>styles-compilation</id> <!-- plugin execution identifier -->
<phase>generate-resources</phase>
<goals>
<goal>update-stylesheets</goal>
</goals>
</execution>
</executions>
</plugin>
Then you need to define a profile in which this plugin will NOT be executed:
<profiles>
<profile>
<id>no-sass</id>
<build>
<plugins>
<plugin>
<groupId>nl.geodienstencentrum.maven</groupId>
<artifactId>sass-maven-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>styles-compilation</id> <!-- here there must be the same identifier as defined in <build><plugins> section -->
<phase>none</phase> <!-- this disables plugin -->
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Now if you run standard maven build:
mvn clean package
the sass-maven-plugin will be executed, yet when running:
mvn clean package -P no-sass
the sass-maven-plugin will not be executed.

Define your pom so that is has only the plugins you need in dev mode
Define a dev profile
Define a production profile which contains all plugins you want/need
Define the production profile as default
example pom:
<profiles>
<profile>
<id>production</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<!--
<plugin>
...
</plugin>
-->
</plugins>
</build>
</profile>
<profile>
<id>dev</id>
<!-- Some other logic here, if necessary.
Otherwise, there's no need for another profile. -->
</profile>
</profiles>
To run in Dev Mode you can call the following:
mvn -Pdev compile
To run in Production Mode just use the normal steps:
mvn compile
In case you don't want/need to define anything special in your dev profile, you can omit its declaration and call your Dev Mode like this (! disables a profile):
mvn -P!production compile
Be aware: you may need to escape the exclamation mark since it is a special character in bash:
mvn -P\!production compile

Building on Krzysiek's answer, you don't need to define explicit executions, just have a look at the output maven gives you and disable the default executions.
For instance, given the following output from maven:
[INFO] --- maven-resources-plugin:2.7:copy-resources (prepare-dockerfile) # tilbud ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
...
[INFO]
[INFO] --- maven-resources-plugin:2.7:resources (default-resources) # tilbud ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
....
[INFO]
[INFO] --- maven-compiler-plugin:3.5.1:compile (default-compile) # tilbud ---
...
[INFO]
[INFO] --- maven-resources-plugin:2.7:testResources (default-testResources) # tilbud ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
...
[INFO]
[INFO] --- maven-compiler-plugin:3.5.1:testCompile (default-testCompile) # tilbud ---
....
The generated default execution names is listed in parenthesis after the plugin and goal. The following profile disables the plugins above:
<profiles>
<profile>
<id>packageOnly</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>default-test</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>default-resources</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testResources</id>
<phase>none</phase>
</execution>
<execution>
<id>prepare-dockerfile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>

Related

How do I create an additional jlink artifact on my jar project?

Using the maven-jlink-plugin, I want to create an additional jlink zip file.
I have configured it like so:
<profile>
<id>jlink</id>
<build>
<plugins>
<!-- to be able to package the application using jlink, all dependencies MUST have a module-info.java. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jlink-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>create-runtime-image</id>
<phase>package</phase>
<goals>
<goal>jlink</goal>
</goals>
<configuration>
<launcher>memeforcehunt=memeforcehunt.app/io.github.alttpj.memeforcehunt.app.cli.MemeforceHuntApp
</launcher>
<modulePaths>
<modulePath>${project.build.directory}/modules</modulePath>
</modulePaths>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
But when I try to execute mvn package -Pjlink, I get an error message: There is already an artifact attached to the project.
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 34.657 s
[INFO] Finished at: 2020-12-17T14:33:04+01:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-jlink-plugin:3.0.0:jlink (create-runtime-image) on project memeforce-app: You have to use a classifier to attach supplemental artifacts to the project instead of replacing them. -> [Help 1]
But I cannot add a classifier to the jlink-plugin?
Tag request
maven-jlink-plugin => maven-jlink-plugin
This was a known issue, reported in MJLINK-49 and MJLINK-26, and solved via MJLINK-52 - classifier support. This will be available in version 3.1.0.
Solution for the upcoming 3.1.0 version
Just add a classifier. It will be supported.
Workaround for pre-3.1.0 versions
However, you can create the archive using a workaround.
Change your packaging to <packaging>jlink</packaging> and add a jar execution:
<packaging>jlink</packaging>
<!-- … -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>create-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>appjar</classifier>
</configuration>
</execution>
</executions>
</plugin>
<plugins>
</build>
You will get two artifacts out of your project:
groupId:artifactId:version:jlink
and
groupId:artifactId:version:jar:appjar
Please note that the jar will now have a classifier.
Tag request
maven-jlink-plugin => maven-jlink-plugin

Integrate jQAssistant in Maven build using profile and running server

I'm trying to integrate jQAssistant into my existing Maven build. I have a hierarchy of POMs, but basically the top POM defines what the build does. That's where I have my <pluginManagement> and my build plugins that are always used. I also have a couple of Maven profiles for special builds.
So, I want to scan all classes during build time and aggregate the results into a running server to have a fully populated Neo4J database after the build of all my Maven modules. The database should contain my whole code base.
Analysing and checking would be a different step, I don't want to do that directly when building a Maven module.
The examples I see all build a local database and then check the classes against it. As far as I understand it, I would have to run the server as a daemon and then configure the Maven plugin to use the 'bolt' URI to populate it - is this right?
Also, since I don't want to slow down the 'normal' build, I added a Maven profile to active the jQAssistant scan. However, this only works on my top POM, but doesn't work in any other Maven project/module. The inheritance of profiles is a normal and expected Maven feature - so what am I doing wrong?
Here's my parent POM. Just to see whether the profile is active, I added PMD as well:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<groupId>foo</groupId>
<artifactId>parent</artifactId>
<version>1.50.0-SNAPSHOT</version>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.buschmais.jqassistant</groupId>
<artifactId>jqassistant-maven-plugin</artifactId>
<version>1.5.0</version>
<configuration>
<useExecutionRootAsProjectRoot>true</useExecutionRootAsProjectRoot>
</configuration>
</plugin>
</pluginManagement>
</build>
<profile>
<id>architecture</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>pmd</goal>
<goal>cpd</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.buschmais.jqassistant</groupId>
<artifactId>jqassistant-maven-plugin</artifactId>
<executions>
<execution>
<id>scan</id>
<goals>
<goal>scan</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</project>
When I run mvn clean package -P architecture on a Maven project with that parent POM, I see the following output, which shows that the profile is active:
09:30:12.316 [INFO]
09:30:12.316 [INFO] --- maven-pmd-plugin:3.5:pmd (default) # util-type ---
09:30:15.073 [INFO]
09:30:15.073 [INFO] --- maven-pmd-plugin:3.5:cpd (default) # util-type ---
09:30:15.976 [INFO]
However, jqassistant-maven-plugin is nowhere.
Now, if I add it to my normal <build> plugins:
<build>
<plugins>
<plugin>
<groupId>com.buschmais.jqassistant</groupId>
<artifactId>jqassistant-maven-plugin</artifactId>
<executions>
<execution>
<id>scan</id>
<goals>
<goal>scan</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
then I see the following output for mvn clean package for my parent POM:
10:38:14.252 [INFO] --- jqassistant-maven-plugin:1.5.0:scan (scan) # parent ---
10:38:15.684 [INFO] Loaded jQAssistant plugins [CDI, Common, Core Analysis, Core Report, EJB3, GraphML, JAX-RS, JPA 2, JSON, JUnit, Java, Java 8, Java EE 6, Maven 3, OSGi, RDBMS, Spring, TestNG, Tycho, XML, YAML].
10:38:15.952 [INFO] Connecting to store at 'file:/C:/jp/maven-parents/parent/target/jqassistant/store/'
10:38:20.058 [INFO] Initializing embedded Neo4j server 3.x
10:38:20.078 [INFO] Resetting store.
10:38:21.515 [INFO] Reset finished (removed 8453 nodes, 29427 relations).
10:38:22.372 [INFO] Entering C:/jp/maven-parents/parent/target/failsafe-reports
10:38:22.378 [INFO] Leaving C:/jp/maven-parents/parent/target/failsafe-reports (1 entries, 4 ms)
However, in my Maven project, I don't see any jQAssistant output.
Starting mvn help:effective-pom -Parchitecture gives me the same output for the parent project and the Maven module:
<plugin>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.5</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>pmd</goal>
<goal>cpd</goal>
</goals>
<configuration>
...
</configuration>
</execution>
</executions>
<configuration>
...
</configuration>
</plugin>
<plugin>
<groupId>com.buschmais.jqassistant</groupId>
<artifactId>jqassistant-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<id>scan</id>
<goals>
<goal>scan</goal>
</goals>
<configuration>
<useExecutionRootAsProjectRoot>true</useExecutionRootAsProjectRoot>
</configuration>
</execution>
</executions>
<configuration>
<useExecutionRootAsProjectRoot>true</useExecutionRootAsProjectRoot>
</configuration>
</plugin>
In my projects I have a parent POM with the following plugin management section:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.buschmais.jqassistant</groupId>
<artifactId>jqassistant-maven-plugin</artifactId>
<version>${jqassistant.version}</version>
<configuration>
<useExecutionRootAsProjectRoot>true</useExecutionRootAsProjectRoot>
</configuration>
<executions>
<execution>
<id>scan</id>
<goals>
<goal>scan</goal>
</goals>
</execution>
<execution>
<id>analyze</id>
<goals>
<goal>analyze</goal>
</goals>
<configuration>
<failOnSeverity>MAJOR</failOnSeverity>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
I also defined the following profile, which I use to run jQAsssistant:
<profile>
<id>verify-architecture</id>
<build>
<plugins>
<plugin>
<groupId>com.buschmais.jqassistant</groupId>
<artifactId>jqassistant-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
Using mvn -P verify-archicture clean install I can scan and analyze my projects.
Here we are, some years later :-)
And coming back to my mistake!
The problem here was the Maven phase. The jQAssistant plugin Mojo scan has the Maven phase post-integration-test by default.
However, we never do mvn clean install in my company, we only do mvn clean package and install using Jenkins, Nexus etc. etc.
So, it was my fault to not force the plugin to the package phase.
That's how it works:
<profile>
<id>jqassistant</id>
<build>
<plugins>
<plugin>
<groupId>com.buschmais.jqassistant</groupId>
<artifactId>jqassistant-maven-plugin</artifactId>
<executions>
<execution>
<id>scan-software</id>
<phase>package</phase>
<goals>
<goal>scan</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

Setting JMeter properties from Maven plugin

I'm trying to set properties for a JMeter test using the Maven plugin. I've followed the recommended settings in my pom.xml file from the answer to this question, but my properties aren't getting picked up when the tests are run.
The relevant parts of the pom.xml:
<profiles>
<profile>
<id>jmeter-test</id>
<build>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>2.0.3</version>
<executions>
<execution>
<id>jmeter-tests</id>
<goals>
<goal>jmeter</goal>
</goals>
<configuration>
<propertiesUser>
<threadCount>5</threadCount>
<environment>test</environment>
</propertiesUser>
<testResultsTimestamp>false</testResultsTimestamp>
<proxyConfig>
<host>localhost</host>
<port>8888</port>
</proxyConfig>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
I am trying to access the variables in my JMeter tests using: ${__P(threadCount)} and ${__P(environment)}.
When running, I'm using
mvn clean verify -Pjmeter-tests
I can see that the proxy configuration is being picked up and used from the output:
[INFO] -------------------------------------------------------
[INFO] P E R F O R M A N C E T E S T S
[INFO] -------------------------------------------------------
[INFO] Invalid value detected for <postTestPauseInSeconds>. Setting pause to 0...
[INFO]
[INFO] Proxy Details:
Host: localhost:8888
[INFO]
[INFO] Executing test: JMeterTests.jmx
Unfortunately the propertiesUser values aren't getting used. I am also able to use the command line runner, which works as expected:
jmeter -n -t JMeterTests.jmx -Jenvironment=test -JthreadCount=5
Any ideas on why this isn't working?
More info:
I've been testing out using the example project, and see that the expected behaviour is that the configuration under <propertiesUser> is supposed to populate the file target/jmeter/bin/user.properties. This isn't happening, the file is not being created at all.
See this FAQ:
https://github.com/jmeter-maven-plugin/jmeter-maven-plugin/wiki/FAQ
Moving the configuration outside the execution block should fix your problem:
<profiles>
<profile>
<id>jmeter-test</id>
<build>
<plugins>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>2.0.3</version>
<executions>
<execution>
<id>jmeter-tests</id>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
</executions>
<configuration>
<propertiesUser>
<threadCount>5</threadCount>
<environment>test</environment>
</propertiesUser>
<testResultsTimestamp>false</testResultsTimestamp>
<proxyConfig>
<host>localhost</host>
<port>8888</port>
</proxyConfig>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

Why won't maven-antrun-plugin run?

I'm having trouble getting the antrun plugin to run.
I have this configuration in my pom:
<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>compile</phase>
<goals><goal>run</goal></goals>
<configuration>
<target>
<echo message="Hello, maven"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
When I run mvn:compile it runs but all I see in the logs about the antrun plugin is this:
[INFO] --- maven-antrun-plugin:1.4:run (default) # datasite-cms ---
project.artifactId
[INFO] Executing tasks
[INFO] Executed tasks
Why isn't the plugin actually doing anything?
Please use an uptodate version of the maven-antrun-plugin if you really need to use maven-antrun-plugin.
The older versions have using the configuration tag: tasks instead of target. But stop using such ancient versions of Maven plugins.

How do I configure the Maven WAR plugin to execute the "inplace" goal by default?

I’m using Maven 3.2.3 and the Maven War 2.6 plugin. I would like the “inlace” goal of the Maven WAR plugin to execute by default (without my having to explicitly specify “war:inlace” on the command line). So I created a profile to include the below
<profile>
<id>dev</id>
<activation>
<property>
<name>!flag</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<filesets>
<fileset>
<directory>${project.basedir}/src/main/webapp/WEB-INF/classes</directory>
</fileset>
<fileset>
<directory>${project.basedir}/src/main/webapp/WEB-INF/lib</directory>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<useCache>true</useCache>
<workDirectory>/tmp/${project.artifactId}/war/work</workDirectory>
</configuration>
<goals>
<goal>inplace</goal>
</goals>
</plugin>
</plugins>
</build>
</profile>
Using “mvn help:active-profiles”, I have verified this profile is being used when I run “mvn clean install” on my WAR project. However, the WAR is not assembled in place. For instance, I get the output
[INFO] Packaging webapp
[INFO] Assembling webapp [myproject] in [/Users/davea/Dropbox/workspace/myproject/target/myproject]
[INFO] Processing war project
[INFO] Copying webapp resources [/Users/davea/Dropbox/workspace/myproject/src/main/webapp]
[INFO] Webapp assembled in [17460 msecs]
Also I notice there are no “classes” or “lib” resources in my src/main/resources/WEB-INF folder. What do I need to configure differently to get my WAR to be built in-place?
This can probably be classified as a duplicate of How to get Maven to run war:exploded but not war:war with a small twist. Instead of exploded it needs to be inplace:
<pluginManagement>
<plugins>
<plugin>
<!-- don't pack the war -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<!-- optional, depends on your setup -->
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
<executions>
<execution>
<id>default-war</id>
<phase>none</phase>
</execution>
<execution>
<id>war-inplace</id>
<phase>package</phase>
<goals>
<goal>inplace</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
<pluginManagement>
The WAR Plugin is responsible for collecting all artifact dependencies, classes and resources of the web application and packaging them into a web application archive.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
</plugin>

Resources