Obfuscate dependencies to single jar with Proguard - maven

I have modular maven application and "module1" depends on "module2" and "module2" depends on "module3" etc.. In module1 I have something like this:
<profile>
<id>obfuscate</id>
<build>
<plugins>
<plugin>
<groupId>com.pyx4me</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<options>
<option>-allowaccessmodification</option>
<option>-keep public class com.test.Main { *; }</option>
</options>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
</libs>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard</artifactId>
<version>${proguard.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
This creates successfully obfuscated "module1". I want to create single jar with all obfuscated dependencies (obfuscated module1 and module2 etc.). Is it possible?

Maven Shade Plugin
This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.
Check it out here.

Try the <assembly> option of the maven-proguard-plugin. Make references to each of the dependencies you wanted bundled into the obfuscated jar. See examples.

If you want package dependency jars into your uber jar, use shade plugin! here's an example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

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 remove version from dependency jar

I'd like to know if there is a way to remove version number from maven dependency.
Let's say for my project I'd like to fetch commons-lang3 3.4 using maven dependency plugin:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
My pom configuration says, it is fetching dependencies to the ./lib directory inside of my project.
What I would like to achieve is remove on the fly version number from commons-lang3-3.4.jar. It would look like:
./lib/commons-lang3.jar
Question: Is there any way to do such thing?
Specifying finalName won't help here.
<build>
<finalName>${project.name}-testing</finalName>
</build>
Below my existing configuration:
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${dir.javaLibs}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
To remove the version from copied dependencies, you can use the stripVersion option of the maven-dependency-plugin:
Strip artifact version during copy
Which has default value to false.
Hence, given your existing configuration, here is the change:
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${dir.javaLibs}</outputDirectory>
<!-- new configuration entry below-->
<stripVersion>true</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

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>

Reference resources from a test-jat artifact

I have two artifact:
artifact-A: contains resources in src/test/resources/
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
artifact B: uses resources from artifact A
<dependency>
<groupId>com.xxxx.yyy</groupId>
<artifactId>artifact-A</artifactId>
<version>3.0-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
The problem is that the resources are never extracted in the project artifact-B.
How can I do that ?
If you define a dependency like this the used jar will never be extracted cause it will be put on the classpath during compilation etc. This means to access the resources from artifact-A you need to access them via the classpath.
In artifact-B, I used the maven-dependency-plugin to extract resources from the test-jar
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>resource-dependencies</id>
<phase>process-test-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>artifact-A</includeArtifactIds>
<includes>**/db-test/*</includes>
<outputDirectory>${project.build.testOutputDirectory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

Resources