How to reference dependency version in Maven? - maven

I am trying to insert value of implementation version to manifest file, but not of current project, as you can see in my code right now (<Implementation-Version>${project.version}</Implementation-Version>):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>ispf-linux</finalName>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>desktop.linux.main.Main</mainClass>
<manifestEntries>
<Implementation-Version>${project.version}</Implementation-Version>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
, but this dependency version. How to do that?
<dependency>
<groupId>registry</groupId>
<artifactId>desktop.common</artifactId>
<version>1.0.0</version>
</dependency>

I would suggest declaring a property for the version:
<properties>
<desktop.common.version>1.0.0</desktop.common.version>
</properties>
Then referencing this property in both places. Here:
<dependency>
<groupId>registry</groupId>
<artifactId>desktop.common</artifactId>
<version>${desktop.common.version}</version>
</dependency>
And here:
<manifestEntries>
<Implementation-Version>${desktop.common.version}</Implementation-Version>
</manifestEntries>

Related

How to prevent a shaded jar to be installed to the local repository

At the end of my "package" step I end up with 2 jars : the one made by the "maven-jar-plugin" and the uber/fat/shaded one made by "maven-shade-plugin".
myapp.jar and myapp-uber.jar
At the "install" phase both jar are copied to the local repository. And I see little (=no) reason to have the uber jar copied to my local repository. Further more, it takes unless place on my HDD. And, anyway it will copied to right location at the "deploy" phase.
Here are those instructions :
<!-- Regular jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>package</phase>
</execution>
</executions>
<configuration>
<archive>
<manifestEntries>
<SplashScreen-Image>icons/splash.png</SplashScreen-Image>
<url>${project.url}</url>
</manifestEntries>
</archive>
</configuration>
</plugin>
<!-- Uber jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>exe</shadedClassifierName>
<finalName>${project.exe_finalname}</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>myapp.MainClass</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<!-- Deploy -->
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>deploy</phase>
<configuration>
<target name="Pushing to builds repository"><!-- ... --></target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
So how can I prevent the uber jar from being copied to the local repository ?
Thanks.

How to create fat jar with tests sources and all dependencies on spring-boot application with TestNG and run tests?

How to create fat jar with tests sources and all dependencies on spring-boot application with TestNG and run tests ?
This is my pom.xml
<?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">
<packaging>jar</packaging>
<properties>
<!-- the main function-->
<start-class>org.kuohai.TestNGMain</start-class>
</properties>
<dependencies>
<dependency>
<groupId>org.uncommons</groupId>
<artifactId>reportng</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8</version>
</dependency>
</dependencies>
<build>
<finalName>packageName</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.16</version>
<executions>
<execution>
<id>default-integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
<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.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/main/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
<properties>
<property>
<name>usedefaultlisteners</name>
<value>false</value>
</property>
<property>
<name>listener</name>
<value>org.uncommons.reportng.HTMLReporter,
org.uncommons.reportng.JUnitXMLReporter
</value>
</property>
</properties>
<forkMode>always</forkMode>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${start-class}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
This is the main function
package org.kuohai;
public class TestNGMain {
public static void main(String[] args) {
org.testng.TestNG.main(args);
}
}
Then you can use :
mvn clean package -DskipTests
Package and run
java -jar packageName.jar -testjar packageName.jar
If you have other questions, you can run java -jar packageName.jar
You can see the message.

shade for parameter resource: Cannot find 'resource' in class org.apache.maven.plugins.shade.resource.ManifestResourceTransformer

I'm working on a maven project. I'm trying to integrate jmh benchmarking into my project. The pom.xml of my maven project...
<parent>
<groupId>platform</groupId>
<artifactId>platform-root</artifactId>
<version>3.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>platform-migration</artifactId>
<packaging>jar</packaging>
<name>Platform Migration</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compile.source>1.7</maven.compile.source>
<maven.compile.target>1.7</maven.compile.target>
<jmh.version>1.1.1</jmh.version>
<jersey-version>2.22.1</jersey-version>
<uberjar.name>rest-benchmarks</uberjar.name>
</properties>
<dependencies>
<dependency>
<groupId>platform</groupId>
<artifactId>platform-commons</artifactId>
<version>${platform.version}</version>
</dependency>
<dependency>
<groupId>platform</groupId>
<artifactId>platform-persistence</artifactId>
<version>${platform.version}</version>
</dependency>
<dependency>
<groupId>platform</groupId>
<artifactId>platform-testing</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>${jersey-version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
When I build my project using "mvn clean install", I got following error
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:3.0.0:shade (default) on project platform-migration: Unable to parse configuration of mojo org.apache.maven.plugins:maven-shade-plugin:3.0.0:shade for parameter resource: Cannot find 'resource' in class org.apache.maven.plugins.shade.resource.ManifestResourceTransformer -> [Help 1]
I don't understand why this error is happening?
Found a cause of this affecting my own setup and am sharing here in case it helps others.
In my case, the cause is a parent pom containing the maven-shade-plugin configuration as well as my own pom. The way that Maven merges these works out incorrectly. It appears the Maven is matching the transformer tags in the order they appear and merging them.
To figure this out, use mvn help:effective-pom and look for the resulting maven-shade-plugin configuration. In my case, a <resource> tag was added to the ManifestResourceTransformer, and this resource matched the first entry in the parent pom's maven-shade-plugin configuration.
Adding an <id> to the <execution> eliminates the problem:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<id>shade-my-jar</id>
...
I suspect both configurations were using the same, default ID. So the key is that each execution of the plugin have a unique id.
The ManifestResourceTransformer allows existing entries in the MANIFEST to be replaced and new entries added.
For example, the following sample sets
the Main-Class entry to the value of the app.main.class property,
the X-Compile-Source-JDK entry to the value of the maven.compile.source property and
the X-Compile-Target-JDK entry to the value of the maven.compile.target property.
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>${app.main.class}</Main-Class>
<X-Compile-Source-JDK>${maven.compile.source}</X-Compile-Source-JDK>
<X-Compile-Target-JDK>${maven.compile.target}</X-Compile-Target-JDK>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I think this is the right Configuration
Your configuration looks wrong:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>xxxxxxxxxxx</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>

How to use maven-shade and felix to generate a shaded jar with a new manifest

I'm currently working on a project that is attempting to integrate use both shade and felix. The goal is to create a shaded jar that contains only the code we need, then use felix to create the manifest we need. The build part of my pom is as follows:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<artifactSet>
<includes>
<include>${project.groupId}:*</include>
</includes>
</artifactSet>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>package</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<manifestLocation>${project.build.directory}</manifestLocation>
<niceManifest>true</niceManifest>
</configuration>
</plugin>
</plugins>
</build>
Now the issue I'm running in to is something I've seen elsewhere, but all of those threads seem to die right at this point. So the shaded jar is correctly created, then Felix runs afterwards and puts the MANIFEST.MF file (which is correct as far as I can tell) in target/classes/META-INF/ but it doesn't put that same manifest in the shaded jar. The one inside the jar is the same manifest that existed before Felix ran.
It almost seems like I need Shade to run, then Felix, then re-run the jar creation. Am I missing something?
I'm trying to figure out how to, for lack of a better term, re-package the JAR with the new manifest.
Your main problem is that the manifest must be generated in the jar file, you can generate your Manifest file from the shade plugin (adapt with your needs):
<configuration>
<transformers>
<!-- This bit sets the main class for the executable jar as you otherwise -->
<!-- would with the assembly plugin -->
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Import-Package>org.apache.common</Import-Package>
<Export-Package>org.test</Export-Package>
<Main-Class>com.br.iacit.tutorialdoJar.ImageLab</Main-Class>
<Specification-Title>Java Advanced Imaging Image I/O Tools</Specification-Title>
<Specification-Version>1.1</Specification-Version>
<Specification-Vendor>Sun Microsystems, Inc.</Specification-Vendor>
<Implementation-Title>com.sun.media.imageio</Implementation-Title>
<Implementation-Version>1.1</Implementation-Version>
<Implementation-Vendor>Sun Microsystems, Inc.</Implementation-Vendor>
</manifestEntries>
</transformer>
<!-- This bit merges the various GeoTools META-INF/services files -->
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
</configuration>
Output Manifest:
Manifest-Version: 1.0
Toto: test
Export-Package: org.test
Archiver-Version: Plexus Archiver
Built-By: NG673AB
X-Compile-Target-JDK: 1.7
Import-Package: org.apache.common
X-Compile-Source-JDK: 1.7
Created-By: Apache Maven 3.3.3
Build-Jdk: 1.8.0_66
Main-Class: tt.tt.main
Edit: I managed to make it so that it compiles correctly, see below:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
<resource>META-INF/MANIFEST.MF</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
<resource>META-INF/MANIFEST.MF</resource>
<file>src/main/resources/MANIFEST.MF</file>
</transformer>
</transformers>
<shadedArtifactAttached>false</shadedArtifactAttached>
<artifactSet>
<includes>
<include>${project.groupId}:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>package</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<manifestLocation>src/main/resources/</manifestLocation>
<niceManifest>true</niceManifest>
<instructions>
<Export-Package>test</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>

Maven update manifest in dependency jars

Webstart requires that all jar files has certain manifest entries, so now I have to go through all dependencies and update each manifest. Is there a way to get maven update manifest files in arbitrary jar files?
Ideally I would like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>target</outputDirectory>
<!-- something like this -->
<manifestEntries>
<Trusted-Library>true</Trusted-Library> <!-- does not work! -->
</manifestEntries>
</configuration>
</execution>
</executions>
</plugin>
Are you sure that every jar need to contains MANIFEST? I think it's needed only in Jar with your entry / main class. You can generate it using maven-jar-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
<manifestEntries>
<Permissions>all-permissions</Permissions>
<Application-Name>Your Application name</Application-Name>
</manifestEntries>
<manifest>
<mainClass>${entry.class}</mainClass>
</manifest>
</archive>
<finalName>${project.artifactId}</finalName>
</configuration>
</plugin>
You could use Webstart Maven Plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>webstart-maven-plugin</artifactId>
<version>1.0-beta-6</version>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>keytool-api-1.7</artifactId>
<version>1.5</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jnlp-inline</goal>
</goals>
</execution>
</executions>
<configuration>
<filenameMapping>simple</filenameMapping>
<versionEnabled>false</versionEnabled>
<jnlpFiles>
<jnlpFile>
<templateFilename>default-jnlp-servlet-template.vm</templateFilename>
<outputFilename>yourJnlp.jnlp</outputFilename>
<jarResources>
<jarResource>
<groupId>your.package</groupId>
<artifactId>ArtifactId</artifactId>
<version>${project.version}</version>
<mainClass>your.main.Class</mainClass>
</jarResource>
</jarResources>
</jnlpFile>
</jnlpFiles>
<unsignAlreadySignedJars>true</unsignAlreadySignedJars>
<canUnsign>true</canUnsign>
<libPath>lib</libPath>
<codebase>$$$codebase</codebase>
<updateManifestEntries>
<Caller-Allowable-Codebase>*</Caller-Allowable-Codebase>
<Trusted-Library>true</Trusted-Library>
<Application-Library-Allowable-Codebase>*</Application-Library-Allowable-Codebase>
<Application-Name>ApplicationName</Application-Name>
<Permissions>all-permissions</Permissions>
<Codebase>*</Codebase>
<Trusted-Only>true</Trusted-Only>
</updateManifestEntries>
<jnlp>
<j2seVersion>1.7+</j2seVersion>
<outputFile>your_jnlp.jnlp</outputFile>
<mainClass>your.class.here</mainClass>
</jnlp>
<sign>
<keystore>${project.basedir}/youekeystore</keystore>
<storepass>...</storepass>
<alias>your_alias</alias>
<verify>false</verify>
</sign>
<verbose>true</verbose>
</configuration>
</plugin>

Resources