Excluding "provided" dependencies from Maven assembly
Asked Answered
A

4

24

I am trying to use the Maven assembly plugin to build a jar-with-dependencies, except those that have provided scope.

I have copied the jar-with-dependencies into an assembly.xml file and configured its use in my pom. Here it is for reference:

<?xml version="1.0" encoding="UTF-8"?>
<assembly>
  <id>injectable-jar</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <unpack>true</unpack>
      <scope>runtime</scope>
    </dependencySet>
  </dependencySets>
  <fileSets>
    <fileSet>
      <directory>${project.build.outputDirectory}</directory>
    </fileSet>
  </fileSets>
</assembly>

I have found out, that if I set the scope to provided, then I can build a jar that contains exactly what I don't want, but I cannot figure out how to get inverse behavior of that.

Augustin answered 22/9, 2009 at 9:21 Comment(5)
What contains the JAR with the assembly that you shows as example? Does it contains only the runtime dependencies?Flong
It seems to contain everything but test-scoped dependencies.Augustin
No, it also has test-scoped dependencies. In what way can that possibly be a sane default, I wonder?Augustin
If you don't use any descriptor, are provided jars included? I think jar-with-dependencies don't include provided scope by default.Tigress
I'm a little confused about what behavior you are seeing and what you're wanting. As of v3.6.0, the plugin defaults to <scope>runtime</scope> by default. For me that seems to exclude all dependencies marked with <scope>provided</scope>, along with their transitive dependencies, as expected. Is that not the behavior you wanted? Have you tried the latest version of the plugin, currently v3.6.0?Grayson
C
24

This is a bit clunky, but you can use the maven-dependency-plugin to copy/unpack all the dependencies into your project, then use the assembly plugin to do the packaging.

The copy-dependencies and unpack-dependencies goals both have an optional excludeScope property you can set to omit the provided dependencies. The configuration below copies all dependencies into target/lib, your assembly plugin descriptor can be modified to use a fileSet to include those jars.

Update: Just tested this to confirm it works. Added the configuration for binding the assembly plugin to the package phase, and the relevant modifications to the assembly descriptor.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <id>copy-dependencies</id>
      <phase>process-resources</phase>
      <goals>
        <goal>copy-dependencies</goal>
      </goals>
      <configuration>
        <excludeScope>provided</excludeScope>
        <outputDirectory>${project.build.directory}/lib</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>
<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>2.2-beta-4</version>
  <executions>
    <execution>
      <id>jar-with-deps</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <descriptors>
      <descriptor>src/main/assembly/my-assembly.xml</descriptor>
    </descriptors>
  </configuration>
</plugin>

The fileSet section of the my-assembly descriptor would look like this:

<assembly>
  <fileSets>
    <fileSet>
      <directory>${project.build.directory}/lib</directory>
      <outputDirectory>/</outputDirectory>
      <includes>
        <include>*.*</include>
      </includes>
    </fileSet>
  </fileSets>
...

</assembly>
Culet answered 22/9, 2009 at 11:53 Comment(3)
I can't figure out how to get it to exclude the one test dependency I have, but apart from that it works perfectly. :)Augustin
this is even clunkier, but if you need to exclude the test scope, you could define multiple executions of the dependency plugin, and in each execution specify a different scope to be included (i.e. to omit test and provided, define two executions, one each for <includeScope>compile</includeScope>, and <includeScope>runtime</includeScope>)Culet
It turns out that one execution is enough. <includeScope>runtime</includeScope> is all I need - it implicitly excludes test, provided and system, which is perfect.Augustin
P
4

In theory the tags "ignoreNonCompile" and "excludeScope" should help, but be warned that they do not necessarily work properly.

With maven3 and the maven-dependency-plugin 2.4, one solution is:

<configuration>
<excludeArtifactIds>junit,mockito-all</excludeArtifactIds>
<excludeTransitive>true</excludeTransitive>
</configuration>
Paynim answered 31/7, 2012 at 20:44 Comment(0)
B
0

With the latest Maven (I was testing on Maven 3.0) this appears to work as expected, with some caveats:

The requested scope (in the dependencySet) may include additional scopes based on the following definition: http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope

Thus, if you request compile scope you will get both compile and provided. However, if you request runtime scope you should get compile and runtime (but not provided).

Benita answered 4/2, 2011 at 0:6 Comment(1)
Would this feature properly exclude provided dependency if it also happens to belong to runtime transitive dependencies the same time?Monoacid
B
0

This is an old post, but the maven-dependency-plugin now has an "excludeScope" option that you can set to "provided" or whatever scope you need.

http://maven.apache.org/plugins/maven-dependency-plugin/copy-dependencies-mojo.html#excludeScope

For example,

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.10</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
                <excludeScope>provided</excludeScope>
            </configuration>
        </execution>
    </executions>
</plugin>
Basseterre answered 21/10, 2016 at 12:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.