41

Maven's assembly plugin enables the creation of a big jar including all dependencies with descriptorRef jar-with-dependencies.

How can one exclude some of these dependencies? It seems like it does not have such a configuration? Is there another solution?

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Jérôme Verstrynge
  • 57,710
  • 92
  • 283
  • 453
  • 1
    Related: if you have excluded some deps at POM level and they are still being included in the assembly output, check out your assembly plugin version. [Pre-3.1.1 has suffered from an exclusion related bug](https://stackoverflow.com/questions/32461192/how-to-have-maven-assembly-plugin-respect-the-exclusions-defined-in-pom-xml#49799612) , and a surprisingly large number of us still use older versions (mine was 2.4 until I explicitly looked this up). – Janaka Bandara Jan 24 '22 at 07:20

4 Answers4

50

Add the <scope>provided</scope> to the dependencies you don't want included in the jar-with-dependencies, e.g.

    <dependency>
      <groupId>storm</groupId>
      <artifactId>storm</artifactId>
      <version>0.6.1-SNAPSHOT</version>
      <scope>provided</scope>
    </dependency>
Jeroen Vuurens
  • 1,171
  • 1
  • 9
  • 10
  • This is the simplest solution and is consistent with WAR targets as well – wrschneider Jul 06 '20 at 18:41
  • I tried this with javafx-controls and javafx-fxml libraries in two different projects. It worked beautifully in the first project. But on the second one, it failed with the compiling many errors such as 'package javafx.beans doesn't exist'. Don't know why. – Guangliang Dec 30 '20 at 17:31
  • Funny to see how I upvoted this answer and now I am having a problem with `provided` JARs being included in the output JAR – wrschneider Jan 14 '22 at 13:10
27

You should use the excludes option available in dependencySet.
Follow below.:

Example in your pom.xml:

...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.3</version>
        <configuration>
          <finalName>../final/${project.artifactId}</finalName>
          <archive>
            <manifest>
              <addClasspath>false</addClasspath>
              <mainClass>com.entrerprise.App</mainClass>
            </manifest>
          </archive>
          <descriptors>
            <descriptor>src/main/resources/jar-with-deps-with-exclude.xml</descriptor>
          </descriptors>
          <appendAssemblyId>false</appendAssemblyId>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
...

Now in your new file jar-with-deps-with-exclude.xml (where dependencySet lives):

 <?xml version="1.0" encoding="UTF-8"?>
    <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
        <id>jar-with-dependencies-and-exclude-classes</id>
        <formats>
          <format>jar</format>
        </formats>
        <includeBaseDirectory>false</includeBaseDirectory>
        <dependencySets>
          <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>false</useProjectArtifact>
            <unpack>true</unpack>
            <scope>runtime</scope>
            <excludes>
              <exclude>junit:junit</exclude>
              <exclude>commons-cli:commons-cli</exclude>
              <exclude>org.apache.maven.wagon:wagon-ssh</exclude>
            </excludes>
           </dependencySet>
        </dependencySets>
        <fileSets>
          <fileSet>
            <outputDirectory>/</outputDirectory>
            <directory>${project.build.outputDirectory}</directory>
          </fileSet>
        </fileSets>
      </assembly>

That's all.

Felipe Pereira
  • 1,368
  • 16
  • 26
  • 9
    Better answer than Raghuram's – Shuai Liu Mar 06 '19 at 08:40
  • Note that the final jar would be like `app-0.0.1-SNAPSHOT-.jar`, just as the original jar is `app-0.0.1-SNAPSHOT-jar-with-dependencies.jar`. If the jar name matters, change the descriptor id to match the original. – WesternGun May 14 '22 at 22:15
  • Great answer, but it would have been nice to know how this relates to the normal jar-with-dependencies descriptor. I managed to dig up the following, for those interested in compare to jar-with-dependencies, compared to using the custom in this example: https://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html#jar-with-dependencies – patrik Sep 29 '22 at 14:47
5

This example indicates one way to do this:

 <dependencySets>
    <dependencySet>
      ....
      <excludes>
        <exclude>commons-lang:commons-lang</exclude>
        <exclude>log4j:log4j</exclude>
      </excludes>
    </dependencySet>
    ....
  </dependencySets>

Essentially we would use the excludes option available in dependencySet.

See also: https://maven.apache.org/plugins/maven-assembly-plugin/assembly-component.html

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
Raghuram
  • 51,854
  • 11
  • 110
  • 122
  • 7
    This gives an error: "Unrecognised tag: 'dependencySets'" for maven3 – zengr Aug 24 '15 at 17:59
  • 35
    This example assumes that I know where dependencySets goes in the pom.xml. A full example would have been helpful. – Ravi Mar 22 '17 at 16:42
  • 5
    The issue here (after 7 yaers) is that this only goes in the assembly definition file, which is not used with 'jar-with-dependencies.' – Andrew T Finnell Oct 24 '18 at 17:58
2

Another alternative is to switch to the much more feature rich maven-shade-plugin which can do this without any external assembly files or marking as "provided" (which may not be what you want as it forces users to have that dependency in their pom). Here is an example:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.3.0</version>
    <configuration>
        <artifactSet>
            <excludes>
                <exclude><group-id>:<artifact-id>:<classifier></exclude>
                <exclude>org.apache.logging.log4j:log4j-core</exclude>
            </excludes>
        </artifactSet>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
</plugin>

https://maven.apache.org/plugins/maven-shade-plugin/index.html

Note that this wont make a jar-with-dependencies but rather an original-jar... and then just the regular output jar. This plugin even lets you filter out specific classes.

Asad-ullah Khan
  • 1,573
  • 18
  • 22