Build fat jar in maven with dependencies only

960 Views Asked by At

I use maven-shade-plugin in my java project.

I have a module called core and i would like to pack all its dependencies into one single jar. I don't wan't to create fat big jar every time and deploy it along with my application code. My application jar has size < 1 MB but dependencies > 20 MB

On my server i would run my application like:

java -cp core.lib.jar:core.jar myApp

I need to deploy only core.jar to my server when i change application code and need to upload core.lib.jar only when i change dependencies (this is very rare).

There's a lot of docs how to build fat jar with java sources but i want to exclude them and deliver it to the server independently.

There is two maven plugins for building fat jar: assembly and shade. I want to stick with shade.

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.3</version>
            <executions>
                <execution>
                    <phase>none</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <artifactSet>
                            <excludes>
                                <exclude>core</exclude>
                            </excludes>
                        </artifactSet>
                    </configuration>
                </execution>
            </executions>
        </plugin>

When i run mvn -pl core shade:shade i get error: core: Failed to create shaded artifact, project main artifact does not exist

I thought that that option: core would exclude my sources from the artifact.

I set phase to none because i don't want to create fat jar when i want to run package. I would like to run mvn shade:shade and have updated fat jar.

I'm not an expert in maven or its plugins, so any help is very appreciated :)

2

There are 2 best solutions below

0
On

I needed to move this block under plugin / configuration

                <artifactSet>
                    <excludes>
                        <exclude>core</exclude>
                    </excludes>
                </artifactSet>

Used to be in executions block.

Now i can run mvn -pl core shade:shade and have fat jar with dependencies only :)

3
On

I haven't used shade plugin by myself so I can't provide any practical guidance, however it seems like you need a multi-module maven project:

  1. Refactor your project (move the folders) to look like this:
my-project
  |__app
  |    |__src 
  |    |  |__main( (and all the production sources/resources inside)
  |    |  |__test (all the tests/test resources inside)
  |    |__pom.xml
  |__core-lib
  |    |__pom.xml
  |__  pom.xml

my-project/pom.xml could be a "multi-module" aggregator: it should have <packaging>pom</packaging> and have the following:

<modules>
  <module>app</module>
  <module>core-lib</module>
</modules>

Now app module could be a place where you write the code of your application. It will change often, but it won't produce any fat jar - only a regular jar with a compiled code from this module only (in your example, it will be 1mb artifact).

The core-lib module will be a module that in it's pom.xml will contain the definitions of the shade / assembly plugin and this module will be responsible for the creation of the "fat jar". In its dependences section it will list all the 3rd party dependencies/code that you'll have to change 'rarely' (in your case, the one with 20 mb artifact).

If you need that, the "app" module could depend on "core-lib" module so that the application will have an access to the classes from the library.

So your usual workflow will be:

cd my-project/app
mvn package

If you want to build both application and core-libraries, then:

cd my-project
mvn package

You can read about multi modules here or here