How to make shaded-jar

What is Shaded jar?

One of the ways to avoid dependency-hell in Java.

Suppose the original code base depends on version X of library A. I want to add a new library B to this codebase. However, library B depends on version Y of library A, Consider the situation where versions X and Y of library A are incompatible.

CodeBase
 |- Library A, Version X
 |- Library B
    |- Library A, Version Y # Conflict!!!

As it is, regardless of whether you select version X or Y of library A, new functions and existing functions You can't move both at the same time.

This is where shaded-jar comes in. The method is to bundle all the Class Y classes of Library A with Library B and create Library B'without dependencies.

CodeBase
 |- Library A, Version X
 |- Library B' (include Library A, Version Y)

relocation However, as it is, the class included in library A and the class of library A included in library B'are placed in the same classpath, so the conflict cannot be resolved.

libraryA-versionX.jar


com.foo.libraryA.Bar.class
...

libraryB'.jar


com.bar.libraryB.Example.class
...
com.foo.libraryA.Bar.class # Conflict!!
...

This is where relocation comes in. By changing the package name of library A included in library B, class conflicts are resolved.

libraryB'.jar


com.bar.libraryB.Example.class
...
shaded.com.foo.libraryA.Bar.class # No Conflict :)
...

In this example, com.foo.libraryA is changed to shaded.com.foo.libraryA. The point is not only to rename it, but also to rewrite all the references to the class of library A included in library B.

How to make shaded-jar

In this article, I will explain how to use maven.

Add the library you want to add as an example com.google.firebase: firebase-admin, Let's say the library you want to avoid conflicts with is com.google.guava: guava.

First, prepare the following pom file.

pom.xml


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>shadeex</artifactId>
    <packaging>jar</packaging>
    <version>1.0.0</version>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.google.firebase/firebase-admin -->
        <dependency>
            <groupId>com.google.firebase</groupId>
            <artifactId>firebase-admin</artifactId>
            <version>6.13.0</version>
        </dependency>
    </dependencies>
        
</project>

Let's check the dependency of firebase-admin.

$ mvn dependency:tree
...
INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ shadeex ---
[INFO] com.example:shadeex:jar:1.0.0
[INFO] \- com.google.firebase:firebase-admin:jar:6.13.0:compile
[INFO]    +- com.google.api-client:google-api-client:jar:1.30.1:compile
[INFO]    |  +- com.google.oauth-client:google-oauth-client:jar:1.30.1:compile
[INFO]    |  \- com.google.http-client:google-http-client-jackson2:jar:1.30.1:compile
[INFO]    |     \- com.fasterxml.jackson.core:jackson-core:jar:2.9.9:compile
[INFO]    +- com.google.api-client:google-api-client-gson:jar:1.30.1:compile
[INFO]    |  \- com.google.http-client:google-http-client-gson:jar:1.30.1:compile
[INFO]    |     \- com.google.code.gson:gson:jar:2.8.5:compile
[INFO]    +- com.google.http-client:google-http-client:jar:1.30.1:compile
[INFO]    |  +- org.apache.httpcomponents:httpclient:jar:4.5.8:compile
[INFO]    |  |  +- org.apache.httpcomponents:httpcore:jar:4.4.11:compile
[INFO]    |  |  +- commons-logging:commons-logging:jar:1.2:compile
[INFO]    |  |  \- commons-codec:commons-codec:jar:1.11:compile
[INFO]    |  +- com.google.code.findbugs:jsr305:jar:3.0.2:compile
[INFO]    |  +- com.google.j2objc:j2objc-annotations:jar:1.3:compile
[INFO]    |  +- io.opencensus:opencensus-api:jar:0.21.0:compile
[INFO]    |  |  \- io.grpc:grpc-context:jar:1.19.0:compile
[INFO]    |  \- io.opencensus:opencensus-contrib-http-util:jar:0.21.0:compile
[INFO]    +- com.google.api:api-common:jar:1.8.1:compile
[INFO]    |  \- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO]    +- com.google.auth:google-auth-library-oauth2-http:jar:0.17.1:compile
[INFO]    |  +- com.google.auto.value:auto-value-annotations:jar:1.6.6:compile
[INFO]    |  \- com.google.auth:google-auth-library-credentials:jar:0.17.1:compile
[INFO]    +- com.google.cloud:google-cloud-storage:jar:1.91.0:compile
[INFO]    |  +- com.google.cloud:google-cloud-core-http:jar:1.90.0:compile
[INFO]    |  |  +- com.google.cloud:google-cloud-core:jar:1.90.0:compile
[INFO]    |  |  |  +- com.google.protobuf:protobuf-java-util:jar:3.9.1:compile
[INFO]    |  |  |  |  \- com.google.errorprone:error_prone_annotations:jar:2.3.2:compile
[INFO]    |  |  |  \- com.google.api.grpc:proto-google-iam-v1:jar:0.12.0:compile
[INFO]    |  |  +- com.google.http-client:google-http-client-appengine:jar:1.31.0:compile
[INFO]    |  |  \- com.google.api:gax-httpjson:jar:0.65.1:compile
[INFO]    |  |     \- org.threeten:threetenbp:jar:1.3.3:compile
[INFO]    |  \- com.google.apis:google-api-services-storage:jar:v1-rev20190624-1.30.1:compile
[INFO]    +- com.google.cloud:google-cloud-firestore:jar:1.31.0:compile
[INFO]    |  +- com.google.cloud:google-cloud-core-grpc:jar:1.91.3:compile
[INFO]    |  |  +- com.google.api:gax:jar:1.49.1:compile
[INFO]    |  |  \- com.google.api:gax-grpc:jar:1.49.1:compile
[INFO]    |  |     +- io.grpc:grpc-stub:jar:1.23.0:compile
[INFO]    |  |     |  \- io.grpc:grpc-api:jar:1.23.0:compile
[INFO]    |  |     +- io.grpc:grpc-auth:jar:1.23.0:compile
[INFO]    |  |     +- io.grpc:grpc-protobuf:jar:1.23.0:compile
[INFO]    |  |     |  \- io.grpc:grpc-protobuf-lite:jar:1.23.0:compile
[INFO]    |  |     +- io.grpc:grpc-netty-shaded:jar:1.23.0:compile
[INFO]    |  |     |  \- io.grpc:grpc-core:jar:1.23.0:compile (version selected from constraint [1.23.0,1.23.0])
[INFO]    |  |     |     +- com.google.android:annotations:jar:4.1.1.4:compile
[INFO]    |  |     |     +- io.perfmark:perfmark-api:jar:0.17.0:compile
[INFO]    |  |     |     \- io.opencensus:opencensus-contrib-grpc-metrics:jar:0.21.0:compile
[INFO]    |  |     \- io.grpc:grpc-alts:jar:1.23.0:compile
[INFO]    |  |        +- io.grpc:grpc-grpclb:jar:1.23.0:compile
[INFO]    |  |        \- org.apache.commons:commons-lang3:jar:3.5:compile
[INFO]    |  +- com.google.api.grpc:proto-google-cloud-firestore-admin-v1:jar:1.31.0:compile
[INFO]    |  |  +- com.google.protobuf:protobuf-java:jar:3.10.0:compile
[INFO]    |  |  \- com.google.api.grpc:proto-google-common-protos:jar:1.17.0:compile
[INFO]    |  +- com.google.api.grpc:proto-google-cloud-firestore-v1:jar:1.31.0:compile
[INFO]    |  +- com.google.api.grpc:proto-google-cloud-firestore-v1beta1:jar:0.84.0:compile
[INFO]    |  \- io.opencensus:opencensus-contrib-grpc-util:jar:0.24.0:compile
[INFO]    +- com.google.guava:guava:jar:26.0-android:compile
[INFO]    |  +- org.checkerframework:checker-compat-qual:jar:2.5.2:compile
[INFO]    |  \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.14:compile
[INFO]    +- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO]    +- io.netty:netty-codec-http:jar:4.1.45.Final:compile
[INFO]    |  +- io.netty:netty-common:jar:4.1.45.Final:compile
[INFO]    |  +- io.netty:netty-buffer:jar:4.1.45.Final:compile
[INFO]    |  \- io.netty:netty-codec:jar:4.1.45.Final:compile
[INFO]    +- io.netty:netty-handler:jar:4.1.45.Final:compile
[INFO]    \- io.netty:netty-transport:jar:4.1.45.Final:compile
[INFO]       \- io.netty:netty-resolver:jar:4.1.45.Final:compile
...

It seems to depend on com.google.guava: guava: jar: 26.0-android: compile. It's unpleasant to depend on the version for ╩╗android, so rewrite it to the version for jdk` Let's add it to the dependency.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>shadeex</artifactId>
    <packaging>jar</packaging>
    <version>1.0.0</version>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.google.firebase/firebase-admin -->
        <dependency>
            <groupId>com.google.firebase</groupId>
            <artifactId>firebase-admin</artifactId>
            <version>6.13.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>26.0-jre</version>
        </dependency>
    </dependencies>
        
</project>

If you check the dependency again, it will be as follows.

$ mvn dependency:tree
...
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ shadeex ---
[INFO] com.example:shadeex:jar:1.0.0
[INFO] +- com.google.firebase:firebase-admin:jar:6.13.0:compile
[INFO] |  +- com.google.api-client:google-api-client:jar:1.30.1:compile
[INFO] |  |  +- com.google.oauth-client:google-oauth-client:jar:1.30.1:compile
[INFO] |  |  \- com.google.http-client:google-http-client-jackson2:jar:1.30.1:compile
[INFO] |  |     \- com.fasterxml.jackson.core:jackson-core:jar:2.9.9:compile
[INFO] |  +- com.google.api-client:google-api-client-gson:jar:1.30.1:compile
[INFO] |  |  \- com.google.http-client:google-http-client-gson:jar:1.30.1:compile
[INFO] |  |     \- com.google.code.gson:gson:jar:2.8.5:compile
[INFO] |  +- com.google.http-client:google-http-client:jar:1.30.1:compile
[INFO] |  |  +- org.apache.httpcomponents:httpclient:jar:4.5.8:compile
[INFO] |  |  |  +- org.apache.httpcomponents:httpcore:jar:4.4.11:compile
[INFO] |  |  |  +- commons-logging:commons-logging:jar:1.2:compile
[INFO] |  |  |  \- commons-codec:commons-codec:jar:1.11:compile
[INFO] |  |  +- io.opencensus:opencensus-api:jar:0.21.0:compile
[INFO] |  |  |  \- io.grpc:grpc-context:jar:1.19.0:compile
[INFO] |  |  \- io.opencensus:opencensus-contrib-http-util:jar:0.21.0:compile
[INFO] |  +- com.google.api:api-common:jar:1.8.1:compile
[INFO] |  |  \- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO] |  +- com.google.auth:google-auth-library-oauth2-http:jar:0.17.1:compile
[INFO] |  |  +- com.google.auto.value:auto-value-annotations:jar:1.6.6:compile
[INFO] |  |  \- com.google.auth:google-auth-library-credentials:jar:0.17.1:compile
[INFO] |  +- com.google.cloud:google-cloud-storage:jar:1.91.0:compile
[INFO] |  |  +- com.google.cloud:google-cloud-core-http:jar:1.90.0:compile
[INFO] |  |  |  +- com.google.cloud:google-cloud-core:jar:1.90.0:compile
[INFO] |  |  |  |  +- com.google.protobuf:protobuf-java-util:jar:3.9.1:compile
[INFO] |  |  |  |  |  \- com.google.errorprone:error_prone_annotations:jar:2.3.2:compile
[INFO] |  |  |  |  \- com.google.api.grpc:proto-google-iam-v1:jar:0.12.0:compile
[INFO] |  |  |  +- com.google.http-client:google-http-client-appengine:jar:1.31.0:compile
[INFO] |  |  |  \- com.google.api:gax-httpjson:jar:0.65.1:compile
[INFO] |  |  |     \- org.threeten:threetenbp:jar:1.3.3:compile
[INFO] |  |  \- com.google.apis:google-api-services-storage:jar:v1-rev20190624-1.30.1:compile
[INFO] |  +- com.google.cloud:google-cloud-firestore:jar:1.31.0:compile
[INFO] |  |  +- com.google.cloud:google-cloud-core-grpc:jar:1.91.3:compile
[INFO] |  |  |  +- com.google.api:gax:jar:1.49.1:compile
[INFO] |  |  |  \- com.google.api:gax-grpc:jar:1.49.1:compile
[INFO] |  |  |     +- io.grpc:grpc-stub:jar:1.23.0:compile
[INFO] |  |  |     |  \- io.grpc:grpc-api:jar:1.23.0:compile
[INFO] |  |  |     +- io.grpc:grpc-auth:jar:1.23.0:compile
[INFO] |  |  |     +- io.grpc:grpc-protobuf:jar:1.23.0:compile
[INFO] |  |  |     |  \- io.grpc:grpc-protobuf-lite:jar:1.23.0:compile
[INFO] |  |  |     +- io.grpc:grpc-netty-shaded:jar:1.23.0:compile
[INFO] |  |  |     |  \- io.grpc:grpc-core:jar:1.23.0:compile (version selected from constraint [1.23.0,1.23.0])
[INFO] |  |  |     |     +- com.google.android:annotations:jar:4.1.1.4:compile
[INFO] |  |  |     |     +- io.perfmark:perfmark-api:jar:0.17.0:compile
[INFO] |  |  |     |     \- io.opencensus:opencensus-contrib-grpc-metrics:jar:0.21.0:compile
[INFO] |  |  |     \- io.grpc:grpc-alts:jar:1.23.0:compile
[INFO] |  |  |        +- io.grpc:grpc-grpclb:jar:1.23.0:compile
[INFO] |  |  |        \- org.apache.commons:commons-lang3:jar:3.5:compile
[INFO] |  |  +- com.google.api.grpc:proto-google-cloud-firestore-admin-v1:jar:1.31.0:compile
[INFO] |  |  |  +- com.google.protobuf:protobuf-java:jar:3.10.0:compile
[INFO] |  |  |  \- com.google.api.grpc:proto-google-common-protos:jar:1.17.0:compile
[INFO] |  |  +- com.google.api.grpc:proto-google-cloud-firestore-v1:jar:1.31.0:compile
[INFO] |  |  +- com.google.api.grpc:proto-google-cloud-firestore-v1beta1:jar:0.84.0:compile
[INFO] |  |  \- io.opencensus:opencensus-contrib-grpc-util:jar:0.24.0:compile
[INFO] |  +- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] |  +- io.netty:netty-codec-http:jar:4.1.45.Final:compile
[INFO] |  |  +- io.netty:netty-common:jar:4.1.45.Final:compile
[INFO] |  |  +- io.netty:netty-buffer:jar:4.1.45.Final:compile
[INFO] |  |  \- io.netty:netty-codec:jar:4.1.45.Final:compile
[INFO] |  +- io.netty:netty-handler:jar:4.1.45.Final:compile
[INFO] |  \- io.netty:netty-transport:jar:4.1.45.Final:compile
[INFO] |     \- io.netty:netty-resolver:jar:4.1.45.Final:compile
[INFO] \- com.google.guava:guava:jar:26.0-jre:compile
[INFO]    +- com.google.code.findbugs:jsr305:jar:3.0.2:compile
[INFO]    +- org.checkerframework:checker-qual:jar:2.5.2:compile
[INFO]    +- com.google.j2objc:j2objc-annotations:jar:1.1:compile
[INFO]    \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.14:compile
...

Now, let's set shaded-jar from here.

pom.xml


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>shadeex</artifactId>
    <packaging>jar</packaging>
    <version>1.0.0</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                          ...
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    ... 
</project>

Use maven-shade-plugin to create shade-jar.

The following are important, so let's explain in detail.

<configuration>
    <artifactSet>
        <includes>
            <include>com.google.guava:guava</include>
            <include>com.google.firebase:firebase-admin</include>
        </includes>
    </artifactSet>
    <relocations>
        <relocation>
            <pattern>com.google</pattern>
            <shadedPattern>com.example.shaded.com.google</shadedPattern>
            <excludes>
                <exclude>com.google.firebase.**</exclude>
            </excludes>
        </relocation>
    </relocations>
</configuration>

Use <artifactSet> to set the list of artifacts included in shaded-jar. This time, the main firebase-admin and the dependent library guava that you want to bundle are specified.

Set relocation with <relocations>. Add the prefix of the java package you want to relocate to <pattern>. guava.jar containscom.google.common. **andcom.google.thirdparty. ** So I specified com.google. On the other hand, firebase-admin containscom.google.firebase. **, Since it is not necessary to relocate firebase-admin itself, it is excluded by<excludes>.

This completes the settings. Let's run it and see what kind of jar is created.

$ mvn package

shaded-jar is output to target / shadeex-1.0.0.jar. If you check the contents, you can see that the class included in guava.jar is certainly relocated.

$ unzip -l target/shadeex-1.0.0.jar  | grep 'com/example/shaded' | head
        0  04-13-2020 17:23   com/example/shaded/
        0  04-13-2020 17:23   com/example/shaded/com/
        0  04-13-2020 17:23   com/example/shaded/com/google/
        0  04-13-2020 17:23   com/example/shaded/com/google/common/
        0  04-13-2020 17:23   com/example/shaded/com/google/common/annotations/
      624  04-13-2020 17:23   com/example/shaded/com/google/common/annotations/Beta.class
      678  04-13-2020 17:23   com/example/shaded/com/google/common/annotations/GwtCompatible.class
      686  04-13-2020 17:23   com/example/shaded/com/google/common/annotations/GwtIncompatible.class
      312  04-13-2020 17:23   com/example/shaded/com/google/common/annotations/VisibleForTesting.class
        0  04-13-2020 17:23   com/example/shaded/com/google/common/base/

On the other hand, the firebase-admin.jar class has not been relocated.

$ unzip -l target/shadeex-1.0.0.jar  | grep -v 'shaded' | grep 'com/google' | head
        0  05-14-2020 19:36   com/google/
        0  05-14-2020 19:36   com/google/firebase/
        0  05-14-2020 19:36   com/google/firebase/messaging/
     1647  05-14-2020 19:36   com/google/firebase/messaging/Notification$Builder.class
     4528  05-14-2020 19:36   com/google/firebase/messaging/AndroidConfig$Builder.class
     1340  05-14-2020 19:36   com/google/firebase/messaging/AndroidFcmOptions$Builder.class
      277  05-14-2020 19:36   com/google/firebase/messaging/TopicManagementResponse$1.class
     1492  05-14-2020 19:36   com/google/firebase/messaging/TopicManagementResponse$Error.class
      409  05-14-2020 19:36   com/google/firebase/messaging/BatchResponse.class
     2910  05-14-2020 19:36   com/google/firebase/messaging/CriticalSound.class

Also, the classes of other dependent libraries are not included.

$ unzip -l target/shadeex-1.0.0.jar  | grep -v 'shaded' | grep -v 'com/google' 
Archive:  target/shadeex-1.0.0.jar
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  06-11-2020 00:24   META-INF/
      135  06-11-2020 00:24   META-INF/MANIFEST.MF
        0  06-11-2020 00:24   META-INF/maven/
        0  06-11-2020 00:24   META-INF/maven/com.example/
        0  06-11-2020 00:24   META-INF/maven/com.example/shadeex/
     2603  06-11-2020 00:24   META-INF/maven/com.example/shadeex/pom.xml
      103  06-10-2020 23:05   META-INF/maven/com.example/shadeex/pom.properties
      599  05-14-2020 19:36   admin_sdk.properties
        0  05-14-2020 19:36   com/
        0  05-14-2020 19:35   META-INF/maven/com.google.firebase/
        0  05-14-2020 19:35   META-INF/maven/com.google.firebase/firebase-admin/
    19833  05-14-2020 19:35   META-INF/maven/com.google.firebase/firebase-admin/pom.xml
      119  05-14-2020 19:36   META-INF/maven/com.google.firebase/firebase-admin/pom.properties
        0  04-13-2020 17:23   META-INF/maven/com.google.guava/
        0  04-13-2020 17:23   META-INF/maven/com.google.guava/guava/
      133  04-13-2020 17:23   META-INF/maven/com.google.guava/guava/pom.properties
    10920  04-13-2020 17:12   META-INF/maven/com.google.guava/guava/pom.xml
        0  04-13-2020 17:23   com/example/
---------                     -------
  8638864                     2699 files

maven-shade-plugin outputs pom.xml for shaded-jar to dependency-reduced-pom.xml.

dependency-reduced-pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>shadeex</artifactId>
  <version>1.0.0</version>
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.2.4</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <artifactSet>
                <includes>
                  <include>com.google.guava:guava</include>
                  <include>com.google.firebase:firebase-admin</include>
                </includes>
              </artifactSet>
              <relocations>
                <relocation>
                  <pattern>com.google</pattern>
                  <shadedPattern>com.example.shaded.com.google</shadedPattern>
                  <excludes>
                    <exclude>com.google.firebase.**</exclude>
                  </excludes>
                </relocation>
              </relocations>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

You can see that the included guava and firebase-admin dependencies have disappeared.

However, there is a problem with this pom. That is, there were other dependent libraries for firebase-admin besides guava.

$ mvn dependency:tree
...
INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ shadeex ---
[INFO] com.example:shadeex:jar:1.0.0
[INFO] \- com.google.firebase:firebase-admin:jar:6.13.0:compile
[INFO]    +- com.google.api-client:google-api-client:jar:1.30.1:compile
[INFO]    |  +- com.google.oauth-client:google-oauth-client:jar:1.30.1:compile
[INFO]    |  \- com.google.http-client:google-http-client-jackson2:jar:1.30.1:compile
[INFO]    |     \- com.fasterxml.jackson.core:jackson-core:jar:2.9.9:compile
[INFO]    +- com.google.api-client:google-api-client-gson:jar:1.30.1:compile
[INFO]    |  \- com.google.http-client:google-http-client-gson:jar:1.30.1:compile
[INFO]    |     \- com.google.code.gson:gson:jar:2.8.5:compile
[INFO]    +- com.google.http-client:google-http-client:jar:1.30.1:compile
[INFO]    |  +- org.apache.httpcomponents:httpclient:jar:4.5.8:compile
[INFO]    |  |  +- org.apache.httpcomponents:httpcore:jar:4.4.11:compile
[INFO]    |  |  +- commons-logging:commons-logging:jar:1.2:compile
[INFO]    |  |  \- commons-codec:commons-codec:jar:1.11:compile
[INFO]    |  +- com.google.code.findbugs:jsr305:jar:3.0.2:compile
[INFO]    |  +- com.google.j2objc:j2objc-annotations:jar:1.3:compile
[INFO]    |  +- io.opencensus:opencensus-api:jar:0.21.0:compile
[INFO]    |  |  \- io.grpc:grpc-context:jar:1.19.0:compile
[INFO]    |  \- io.opencensus:opencensus-contrib-http-util:jar:0.21.0:compile
[INFO]    +- com.google.api:api-common:jar:1.8.1:compile
[INFO]    |  \- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO]    +- com.google.auth:google-auth-library-oauth2-http:jar:0.17.1:compile
[INFO]    |  +- com.google.auto.value:auto-value-annotations:jar:1.6.6:compile
[INFO]    |  \- com.google.auth:google-auth-library-credentials:jar:0.17.1:compile
[INFO]    +- com.google.cloud:google-cloud-storage:jar:1.91.0:compile
[INFO]    |  +- com.google.cloud:google-cloud-core-http:jar:1.90.0:compile
[INFO]    |  |  +- com.google.cloud:google-cloud-core:jar:1.90.0:compile
[INFO]    |  |  |  +- com.google.protobuf:protobuf-java-util:jar:3.9.1:compile
[INFO]    |  |  |  |  \- com.google.errorprone:error_prone_annotations:jar:2.3.2:compile
[INFO]    |  |  |  \- com.google.api.grpc:proto-google-iam-v1:jar:0.12.0:compile
[INFO]    |  |  +- com.google.http-client:google-http-client-appengine:jar:1.31.0:compile
[INFO]    |  |  \- com.google.api:gax-httpjson:jar:0.65.1:compile
[INFO]    |  |     \- org.threeten:threetenbp:jar:1.3.3:compile
[INFO]    |  \- com.google.apis:google-api-services-storage:jar:v1-rev20190624-1.30.1:compile
[INFO]    +- com.google.cloud:google-cloud-firestore:jar:1.31.0:compile
[INFO]    |  +- com.google.cloud:google-cloud-core-grpc:jar:1.91.3:compile
[INFO]    |  |  +- com.google.api:gax:jar:1.49.1:compile
[INFO]    |  |  \- com.google.api:gax-grpc:jar:1.49.1:compile
[INFO]    |  |     +- io.grpc:grpc-stub:jar:1.23.0:compile
[INFO]    |  |     |  \- io.grpc:grpc-api:jar:1.23.0:compile
[INFO]    |  |     +- io.grpc:grpc-auth:jar:1.23.0:compile
[INFO]    |  |     +- io.grpc:grpc-protobuf:jar:1.23.0:compile
[INFO]    |  |     |  \- io.grpc:grpc-protobuf-lite:jar:1.23.0:compile
[INFO]    |  |     +- io.grpc:grpc-netty-shaded:jar:1.23.0:compile
[INFO]    |  |     |  \- io.grpc:grpc-core:jar:1.23.0:compile (version selected from constraint [1.23.0,1.23.0])
[INFO]    |  |     |     +- com.google.android:annotations:jar:4.1.1.4:compile
[INFO]    |  |     |     +- io.perfmark:perfmark-api:jar:0.17.0:compile
[INFO]    |  |     |     \- io.opencensus:opencensus-contrib-grpc-metrics:jar:0.21.0:compile
[INFO]    |  |     \- io.grpc:grpc-alts:jar:1.23.0:compile
[INFO]    |  |        +- io.grpc:grpc-grpclb:jar:1.23.0:compile
[INFO]    |  |        \- org.apache.commons:commons-lang3:jar:3.5:compile
[INFO]    |  +- com.google.api.grpc:proto-google-cloud-firestore-admin-v1:jar:1.31.0:compile
[INFO]    |  |  +- com.google.protobuf:protobuf-java:jar:3.10.0:compile
[INFO]    |  |  \- com.google.api.grpc:proto-google-common-protos:jar:1.17.0:compile
[INFO]    |  +- com.google.api.grpc:proto-google-cloud-firestore-v1:jar:1.31.0:compile
[INFO]    |  +- com.google.api.grpc:proto-google-cloud-firestore-v1beta1:jar:0.84.0:compile
[INFO]    |  \- io.opencensus:opencensus-contrib-grpc-util:jar:0.24.0:compile
[INFO]    +- com.google.guava:guava:jar:26.0-android:compile
[INFO]    |  +- org.checkerframework:checker-compat-qual:jar:2.5.2:compile
[INFO]    |  \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.14:compile
[INFO]    +- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO]    +- io.netty:netty-codec-http:jar:4.1.45.Final:compile
[INFO]    |  +- io.netty:netty-common:jar:4.1.45.Final:compile
[INFO]    |  +- io.netty:netty-buffer:jar:4.1.45.Final:compile
[INFO]    |  \- io.netty:netty-codec:jar:4.1.45.Final:compile
[INFO]    +- io.netty:netty-handler:jar:4.1.45.Final:compile
[INFO]    \- io.netty:netty-transport:jar:4.1.45.Final:compile
[INFO]       \- io.netty:netty-resolver:jar:4.1.45.Final:compile

However, dependency-reduced-pom.xml removes the dependencies of these libraries.

The option to solve this problem is <promoteTransitiveDependencies>. By specifying this option, all dependent libraries of firebase-admin will be listed as direct dependencies of dependency-reduced-pom.xml, after which firebase-admin and guava will be removed. ..

Therefore, the dependencies of libraries that are not included can be left correctly.

The final pom.xml looks like this:

pom.xml


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>shadeex</artifactId>
    <packaging>jar</packaging>
    <version>1.0.0</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <promoteTransitiveDependencies>true</promoteTransitiveDependencies>
                            <artifactSet>
                                <includes>
                                    <include>com.google.guava:guava</include>
                                    <include>com.google.firebase:firebase-admin</include>
                                </includes>
                            </artifactSet>
                            <relocations>
                                <relocation>
                                    <pattern>com.google</pattern>
                                    <shadedPattern>com.example.shaded.com.google</shadedPattern>
                                    <excludes>
                                        <exclude>com.google.firebase.**</exclude>
                                    </excludes>
                                </relocation>
                            </relocations>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.google.firebase/firebase-admin -->
        <dependency>
            <groupId>com.google.firebase</groupId>
            <artifactId>firebase-admin</artifactId>
            <version>6.13.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>29.0-jre</version>
        </dependency>
    </dependencies>
        
</project>

On the other hand, the dependency-reduced-pom.xml output by executing the mvn package is as follows.

dependency-reduced-pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>shadeex</artifactId>
  <version>1.0.0</version>
  <build>
    ...
  </build>
  <dependencies>
    <dependency>
      <groupId>com.google.api-client</groupId>
      <artifactId>google-api-client</artifactId>
      <version>1.30.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.google.oauth-client</groupId>
      <artifactId>google-oauth-client</artifactId>
      <version>1.30.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.google.http-client</groupId>
      <artifactId>google-http-client-jackson2</artifactId>
      <version>1.30.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.9</version>
      <scope>compile</scope>
    </dependency>
    ...
  </dependencies>
</project>

The dependent libraries for firebase-admin remain correct.

All you have to do now is upload this jar and dependency-reduced-pom.xml to your internal maven repository.

References

Apache Maven Shade Plugin

Recommended Posts

How to make shaded-jar
Java --How to make JTable
[Rails] How to make seed
How to make a splash screen
How to make a Jenkins plugin
How to make a Maven project
How to make a Java array
[Android] How to make Dialog Fragment
How to use identity
How to make Unity Native Plugin (Android version)
How to use hashes
How to write Mockito
How to install MySQL
How to write migrationfile
How to build android-midi-lib
How to use Dozer.mapper
How to use Gradle
How to use org.immutables
How to use java.util.stream.Collector
How to use VisualVM
How to make an crazy Android music player
[Java] How to make multiple for loops single
How to use Map
How to type backslash \
How to concatenate strings
How to make a cache without thinking too much
How to make a mod for Slay the Spire
How to update with activerecord-import
How to set Java constants
Ruby: How to use cookies
How to use dependent :: destroy
How to write Junit 5 organized
How to use Eclipse Debug_Shell
How to use Apache POI
How to terminate rails server
How to write Rails seed
[Rails] How to use validation
How to use Java variables
[Rails] How to disable turbolinks
[iOS] How to read Carthage
How to check JSF version
How to handle an instance
[Rails] How to use authenticate_user!
How to convert Java radix
How to use GC Viewer
[Rails] How to implement scraping
[Rails] How to install simple_calendar
[Java] How to implement multithreading
[Rails] How to install reCAPTCHA
How to use Lombok now
How to install JDK8-10 (Mac)
How to initialize Java array
How to insert a video
How to create a method
How to rollback migration files
[Creating] How to use JUnit
[Rails] How to use Scope
How to authorize using graphql-ruby
How to make an app using Tensorflow with Android Studio
What is an immutable object? [Explanation of how to make]
How to master programming in 3 months