Create shaded and non shaded jars in Maven in same module? - maven

Is it possible to create 2 jars upon maven build:
Shaded jar (uber)
Non shaded jar
I'd like to have both published to maven local. Thanks.

The configuration can be given as follows will create an jar file (done by default) and the following will create a xyz-1.0-shaded.jar supplemental:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>

Related

how to include static resource from a dependency in spring boot fat jar at the time of build

I have a spring boot application whose UI separately is built and added as a dependency to my application. Now I want to unpack the dependency and add to the resource folder of the spring boot application at the time of build so that it becomes a part of fat jar. Could someone guide me as to how this can be done with spring-boot-maven-plugin.
note: the project is using maven for build
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>nflow-explorer</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>io.nflow</includeGroupIds>
<includeArtifactIds>nflow-explorer</includeArtifactIds>
<outputDirectory>
${project.build.directory}/resources/main/static/explorer
<!-- or: ${project.basedir}/wherever/you/want/it -->
</outputDirectory>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.6.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
You don't have to unpack the JAR.
Simply use the Maven Resource Plugin http://maven.apache.org/plugins/maven-resources-plugin/index.html
You can specify directories to include like this:
<project>
...
<build>
...
<resources>
<resource>
<directory>[your folder here]</directory>
</resource>
</resources>
...
</build>
...
</project>

maven shade plugin seems not to use classifier name

When I create a jar file with maven and use profiles with a classifier, the shaded jar file does not have the classifier in the name.
Maven version: Apache Maven 3.2.5
Here is one of the profiles:
<profile>
<id>external</id>
<properties>
<envClassifier>external</envClassifier>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<configuration>
<classifier>external</classifier>
</configuration>
<id>external-package</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
However, the target jar files are not named as I expected (you can see the large shaded jar #111MB doesn't have the classified name of 'external':
363 KB original-myjar-0.1-SNAPSHOT.jar
111 MB myjar-0.1-SNAPSHOT.jar
362 KB myjar-0.1-SNAPSHOT-external.jar
Here is my shading configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin.version}</version>
<configuration>
<createDependencyReducedPom>true
</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
---removed
</configuration>
</execution>
</executions>
</plugin>
I could use shadedArtifactId to force the name of the output file but it seems like that shouldn't be needed.
Any ideas?
Thanks
From my experience, the shade plugin takes the primary artifact and replaces it with the shaded one.
If you want the shaded artifact to have a classifier, you should add these configurations to the shade plugin:
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>external</shadedClassifierName>
It's not clear to me why you need the profiles or the additional jar plugin configuration with the classifier. I think you can just use the shade plugin to generate the classified jar that you want. Clarify if there is some requirement forcing you to use profiles.
So I was able to get this working by using the finalName property. Would be curious to here if others use this technique or if there are other solutions.
<profile>
<id>external</id>
<properties>
<envClassifier>internal</envClassifier>
</properties>
<build>
<finalName>${project.artifactId}-${project.version}-external</finalName>
</build>
</profile>
</profiles>

Spring Boot Executable Jar File Without Dependencies

What is the easiest way to build spring boot jar file without its dependencies?
Basically I should be able to keep dependency jar files in a separate folder.
Currently I'm using spring boot maven plugin, however, it creates a Fat jar file with all dependencies.
Just do not use spring-boot-maven-plugin at all and use JAR packaging. This way the build wouldn't package dependencies into the JAR.
spring-boot-maven-plugin has option for repackaging that puts dependencies inside (making uber jar)
You can disable repackaging or make repackaged .jar go with other classifier [2]
http://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-maven-plugin.html
http://docs.spring.io/spring-boot/docs/current/maven-plugin/examples/repackage-classifier.html
Below is a solution I found on How to Create an Executable JAR with Maven,
You just need to put these in your plugins.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>
org.baeldung.executable.ExecutableMavenJar
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Replace change your build entry in pom.xml to
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/dependency_jar</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
In the target folder there will be a dependency_jar folder with all the dependency jars, along with "project_name.jar"(fat jar) and "project_name.jar.original"(jar file of your code)

Can I produce both jar and war of a project in maven?

I have a project(A) in maven that has packaging of war. One other project(B) depends on A and it needs project A jar file but in phase of compile, the war of project A will produce and no jar is available for project B.
How can I create a jar of project A in phase of compile so that project B can use it?
I would suggest to go a different way and use the maven-war-plugin which can produce a separate artifact for the classes which can be used like the following:
<dependency>
<groupId>myGroup</groupId>
<artifactId>myArtifact</artifactId>
<version>myVersion</myVersion>
<classifier>classes</classifier>
</dependency>
This can be achieved by using the following configuration in your war module:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
...
</plugins>
I found the solution : :)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>make-a-jar</id>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<packaging>jar</packaging>
<artifactId>${project.artifactId}</artifactId>
<groupId>${project.groupId}</groupId>
<version>${project.version}</version>
<file>
${project.build.directory}/${project.artifactId}-${project.version}.jar
</file>
</configuration>
</execution>
</executions>
</plugin>

remove jar created by default in maven

I am using maven assembly plugin. in my pom.xml, pakaging type: jar and i dont use maven jar plugin.
Whenever i run mvn clean package, it create 2 jar files: one is from maven assembly, another one is created by default (due to packaging type =jar). I want to keep only the jar file created by assembly plugin only. How to do that?
You may have your reasons but I doubt that it is a good solution to skip the default jar being built and deployed.
Anyhow here is how you can disable the default jar being built.
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<id>make-assembly</id>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- some configuration of yours... -->
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-jar</id>
<!-- put the default-jar in the none phase to skip it from being created -->
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>

Resources