Replace task in Maven Antrun Plugin - maven

I am using antrun plugin in my maven build to replace a token #version# in some of the JSP files with the application version.
This is what I am doing:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<target>
<echo>${displayVersion}</echo>
<replace file="src/main/webapp/admin/decorators/default.jsp" token="#version#" value="${displayVersion}"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
I am passing displayVersion as a parameter to maven
mvn clean install -DdisplayVersion="Version-1.1"
And this is the console output for Antrun Plugin
[INFO] [antrun:run {execution: default}]
[INFO] [antrun:run {execution: default}]
[INFO] Executing tasks
main:
[echo] 9.4_70
[INFO] Executed tasks
Although the property is being echoed properly, it's not substituted in my JSP.
The #version# token is replaced by {displayVersion} and not it's actual value.

Use Maven Resources Filtering as Aaron suggested and set the delimiters in the Maven Resource Plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<delimiters>
<!-- enable maven's standard delimiters -->
<delimiter>${*}</delimiter>
<!-- enable your #delimiters# -->
<delimiter>#</delimiter>
</delimiters>
</configuration>
</plugin>

The Maven resources plugin can replace variables in resources; so if you deliver the JSP (instead of compiling it with the jspc plugin), you can simply let the resource plugin do the work while it copies resources by enabling filtering.

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

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>

Execute script as part of mvn package

My pom.xml contains
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<warName>${project.artifactId}</warName>
<outputDirectory>${wlp.install.dir}/usr/servers/liberty/apps</outputDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
When I run mvn package I can see this step running:
[INFO] --- maven-war-plugin:2.3:war (default-war) # frontEnd ---
That's great. However, I also want to run a shell script before the war file is created. I tried adding
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<configuration>
<tasks>
<exec dir="${basedir}"
executable="${basedir}/src/main/webapp/concat"/>
</tasks>
</configuration>
</plugin>
before the maven-war plugin, but it does not run. I don't even see antrun in the output of mvn. Adding the <tasks> element to the <configuration> for maven-war-plugin does nothing either.
What can I do to have maven simply run a script as part of mvn package?
The position in the pom.xml is irrelevant, you have to bind the maven-antrun-plugin execution to the correct lifecycle phase (e.g. compile) as shown below:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase> <!-- a lifecycle phase --> </phase>
<configuration>
<target>
<!--
Place any Ant task here. You can add anything
you can add between <target> and </target> in a
build.xml.
-->
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
See The maven-antrun-plugin Usage Page for more details and The Maven Introduction to the Build Lifecycle for further reference.

Disable maven plugins when using a specific profile

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>

Resources