Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude Java package from dependency jar

I want to use jar from third party vendor. But in this jar I have old version of Java package org.osgi.framework I need to find some way to exclude the package from the main project. Something like this:

<dependency>
      <groupId>com.ibm</groupId>
          <artifactId>com.ibm.ws.admin.client</artifactId>
          <version>8.5.0</version>
          <exclusions>
             <exclusion>org.osgi.framework</exclusion>
          </exclusions>
          <type>jar</type>
</dependency>

Can you recommend some solution?

like image 336
Peter Penzov Avatar asked Jan 22 '16 20:01

Peter Penzov


1 Answers

Although a better solution would be to re-pack the dependency (without the unwanted package) with a classifier (as described in this answer) and publish it on your enterprise Maven repository (or install it into your local Maven cache, if it's a personal project), below is a different solution which should also suit your needs.

You could have a multi-module Maven project, having a module with just this dependency and in it you could use the Maven Shade Plugin and its filters property as explained in its official example.

As per documentation, the filters element:

Archive Filters to be used. Allows you to specify an artifact in the form of a composite identifier as used by artifactSet and a set of include/exclude file patterns for filtering which contents of the archive are added to the shaded jar

In your case, the following configuration should apply the filter:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.3</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <filters>
                            <filter>
                                <artifact>com.ibm:com.ibm.ws.admin.client</artifact>
                                <excludes>
                                    <exclude>org/osgi/framework/**</exclude>
                                </excludes>
                            </filter>
                        </filters>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

The generated jar from the package phase should not contain that package any longer. As part of the Maven output you should see:

[INFO] --- maven-shade-plugin:2.4.3:shade (default) @ test-checksum ---
[INFO] Including com.ibm:com.ibm.ws.admin.client:jar:8.5.0 in the shaded jar.
[INFO] Replacing original artifact with shaded artifact.

You can verify the content of the generated jar, the filtered package should not be there.

Then, the output of this module will have the "new"/filtered jar you were looking for. Then the consumer module would just need to have a dependency on this module and as such have the filter applied.
An example of such a multimodule project would be:

+ aggregator/parent project
    - filtered-dependency-module (applying the shade filter)
    - consumer-module (having dependency on the filtered module)

Update
Further note: in the module which applies the filter, you should declare the dependency as optional so that the consumer module doesn't bring it in transitively again.

<dependencies>
    <dependency>
        <groupId>com.ibm</groupId>
        <artifactId>com.ibm.ws.admin.client</artifactId>
        <version>8.5.0</version>
        <optional>true</optional>
    </dependency>
</dependencies>

Optional doesn't affect the module itself, only the consumer one. And the Shade plugin will keep on working (I re-tested it, just in case).

like image 133
A_Di-Matteo Avatar answered Oct 11 '22 00:10

A_Di-Matteo