Hello people of stackoverflow, on my working project I have 5 dependencies.
I'm working on a project which doesn't contain any main method.
What I would like to do is including 2 (HikariCP and slf4j) out of my 5 dependencies in the final jar, but I don't figure how to do this, it's always adding all of them.
Edit: I'm using eclipse
Using Maven
You can use the maven-shade-plugin to generate a fat-jar (or uber-jar). It will package all your dependencies inside the jar:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<finalName>YOUR_JAR_FINAL_NAME</finalName>
</configuration>
</plugin>
</plugins>
</build>
Documentation related to the maven-shade-plugin can be found in here
UPDATE: As you want to include just a few dependencies inside of it, you can check the Selecting contents for Uber JAR section:
You can use the include or exclude tag to select which content will be provided to the jar, you can find some examples from the docs below:
Excluding
<configuration>
<artifactSet>
<excludes>
<exclude>classworlds:classworlds</exclude>
<exclude>junit:junit</exclude>
<exclude>jmock:*</exclude>
<exclude>*:xml-apis</exclude>
<exclude>org.apache.maven:lib:tests</exclude>
<exclude>log4j:log4j:jar:</exclude>
</excludes>
</artifactSet>
</configuration>
Including and excluding
<configuration>
<filters>
<filter>
<artifact>junit:junit</artifact>
<includes>
<include>junit/framework/**</include>
<include>org/junit/**</include>
</includes>
<excludes>
<exclude>org/junit/experimental/**</exclude>
<exclude>org/junit/runners/**</exclude>
</excludes>
</filter>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
UPDATE 2: For a runnable jar file, you can follow this section of the documentation related to Executable Jars
In Eclipse
You can use the Package required libraries into generated JAR option, the downside of it is that you can't really select which dependencies do you want to include into to, since it is assessing all the required libs for you project.
I believe if you really want to remove some stuff, you would need to use Maven to package, or remove manually the dependencies you don't like from the generated jar, generating a custom jar with your own hands:
Related
In a project, I use as a dependancy an artifact which is in the same groupId than this project.
The dependancy is well imported and used in my IDE, but when I compile the jar, no classes from the dependancy are copied inside the final jar. So I get exceptions at runtime...
Why ???
The dependancy POM head :
<groupId>com.example.things</groupId>
<artifactId>project-foo</artifactId>
My project POM head :
<groupId>com.example.things</groupId>
<artifactId>project-bar</artifactId>
My project POM section to declare dependancy :
<dependency>
<groupId>com.example.things</groupId>
<artifactId>example-foo</artifactId>
<version>1.2.345-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
My project POM Maven Shade Section :
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<artifactSet>
<includes>
<include>com.example.things:project-foo</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
Thanks for helping, it seems I do something wrong...
I have a legacy code (which suppose to be 100% working) without any documentation. This code consists of several separate services which do some tasks (like working with RabbitMQ, inserting some records into Postgres DB, and so on).
Each and every service in its pom.xml in maven-shade-plugin configuration has resourses folder being excluded from the resulting jar. Like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin-version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>log4j2.xml</exclude>
<exclude>application.properties</exclude>
<exclude>update.sql</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
As a result, when I try to run any of such jars (with java -jar any_of_my_jars.jar) - they fail, cuz they need application.properties and all other resources to run.
So the question is: it should be I'm missing something. I either should run them in some other way, or I should deploy them somewhere. Can someone plz explain to me how such jars can be used to be working jars?
I am depending on a library in my Maven project and I find that the library's JAR contains some packages which cause my application to fail. I believe the library should still work if I can somehow exclude these packages, but I would like to do this via Maven, rather than by hacking the JAR file myself. Is there a way to do this with Maven?
You can take a look at the maven-shade-plugin. An example is shown in the official docs.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>junit:junit</artifact>
<includes>
<include>junit/framework/**</include>
<include>org/junit/**</include>
</includes>
<excludes>
<exclude>org/junit/experimental/**</exclude>
<exclude>org/junit/runners/**</exclude>
</excludes>
</filter>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
I am using the Maven-Shade-Plugin to create a runnable Uber-jar.
According to the last frame on this page, the size of the jar can be minimized by using:
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
But this feature does not take into consideration the classes that are declared in the log4j.properties file. Hence, e.g. org.apache.log4j.appender.TimeAndSizeRollingAppender is not included in the Uber-jar, even though it’s declared in the log4j.properties file.
I believe I will face the same problem with Spring. If my code only refers to interface A and my Spring file contains an instantiation of class B that implements A, then B might not be added to the jar, since it’s not in the code.
How can I solve this problem?
This functionality has been added to version 1.6 of the maven-shade-plugin (just released). minimizeJar will now not remove classes that have been specifically included with filters. Note that including some of an artifact's classes in a filter will exclude non-specified classes for that artifact, so be sure to include all the classes that you need.
Here's an example plugin config:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>log4j:log4j</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>commons-logging:commons-logging</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
To only include specific classes, add them as includes using path slashes in the class name in a filter (again, non-included classes will be automatically excluded).
<filter>
<artifact>org.yourorg:your-artifact</artifact>
<includes>
<include>org/yourorg/yourartifact/api/*</include>
<include>org/yourorg/yourartifact/util/*</include>
</includes>
</filter>
I am trying to minimize the UberJar's size by using Maven Shade Plugin's minimizeJar. It looks like minimizeJar only includes classes that are statically imported in the code (I suspect this because I see LogFactory.class in uber jar at org\apache\commons\logging\ but no classes of the impl package are included, hence throwing java.lang.ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl when I run the uber-jar).
Is there any way I can tell Maven's Shade plugin to include specified packages into the final jar no matter what the minimizeJar suggests?
Here the pom snippet of what I am trying:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>commons-logging:commons-logging</artifact>
<includes>
<include>org/apache/commons/logging/**</include>
</includes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.myproject.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
This functionality has been added to version 1.6 of the maven-shade-plugin (just released). minimizeJar will now not remove classes that have been specifically included with filters. Note that including some of an artifact's classes in a filter will exclude non-specified classes for that artifact, so be sure to include all the classes that you need.
Here's an example plugin config:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>log4j:log4j</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>commons-logging:commons-logging</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
I am using the 2.0 version of the Maven Shade Plugin and still I am not able to include classes after "minimizing" the JAR.
As a workaround the only thing that comes to my mind is to create references to the needed classes to avoid the minimization code to get rid of them. ie:
/*
* This block prevents the Maven Shade plugin to remove the specified classes
*/
static {
#SuppressWarnings ("unused") Class<?>[] classes = new Class<?>[] {
JButton.class,
JMenu.class,
JMenuBar.class,
JMenuItem.class
};
}
I hope Maven developers implement a way to handle this situation (which I guess is very common).