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

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

Related

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>

Maven License Plugin: The parameters 'organizationName', ... are missing or invalid

I'm trying to use the maven license plugin version 1.9. I'm running the goal update-license-header however I get the following error:
[ERROR] Failed to execute goal org.codehaus.mojo:license-maven-plugin:1.9:update-file-header (default-cli) on project myproject: The parameters 'organizationName', 'inceptionYear' for goal org.codehaus.mojo:license-maven-plugin:1.9:update-file-header are missing or invalid -> [Help 1]
My pom.xml looks like this
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>1.9</version>
<configuration>
<verbose>false</verbose>
<addSvnKeyWords>true</addSvnKeyWords>
</configuration>
<executions>
<execution>
<id>first</id>
<goals>
<goal>update-file-header</goal>
</goals>
<phase>process-sources</phase>
<configuration>
<licenseName>gpl_v3</licenseName>
<organizationName>My Organization</organizationName>
<inceptionYear>2017</inceptionYear>
<roots>
<root>src/main/java</root>
<root>src/test</root>
</roots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
You can solve this issue by adding
<organizationName>My Organization</organizationName>
<inceptionYear>2017</inceptionYear>
to the project tag of your pom.xml

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>

Maven JavaDoc Plugin: Aggregate Dependencies

I am attempting to compile JavaDocs with:
mvn javadoc:aggregate
I keep getting errors such as:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.5:aggregate (default-cli) on project mutopia: An error has occurred in JavaDocs report generation:Exit code: 1 - /Users/Aram/Development/Java/MUtopia/Code/mutopia/mutopia-server/src/main/java/au/edu/unimelb/civenv/hpvat/mutopia/server/Asset.java:3: package org.springframework.roo.addon.javabean does not exist
[ERROR] import org.springframework.roo.addon.javabean.RooJavaBean;
and
[ERROR] /Users/Aram/Development/Java/MUtopia/Code/mutopia/mutopia-server/src/main/java/au/edu/unimelb/civenv/hpvat/mutopia/server/Param.java:8: package flexjson does not exist
[ERROR] import flexjson.JSONDeserializer;
Clearly my dependencies for a multi-module/aggregation project are not being recognised. Both these are marked as dependencies in one of my modules' pom.xml file. Do I need to provide additional arguments to maven-javadoc-plugin in the parent pom.xml?
EDIT:
I ran mvn install and it seemed to work. My parent pom.xml is:
<build>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.5</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
</plugin>
...
</build>
The version is outdated but that didn't seem to be the problem.
You need to go via the pom configuration like this:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<configuration>
<!-- Default configuration for all reports -->
...
</configuration>
<executions>
<execution>
<id>aggregate</id>
<goals>
<goal>aggregate</goal>
</goals>
<phase>site</phase>
<configuration>
<!-- Specific configuration for the aggregate report -->
...
</configuration>
</execution>
...
</executions>
</plugin>
...
</plugins>
</build>
...
</project>
and than you need to call mvn site ...

Resources