[Java] How to make shaded-jar

10 minute read

What is # Shaded jar One of the ways to avoid dependency-hell in Java.

Suppose the original codebase depends on version A 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 not compatible.

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

Under this condition, no matter which version X or Y of library A is selected, new and existing functions will be You cannot move both at the same time.

Here is shaded-jar. The method is to create all the classes of version A of Library A in Library B and create a 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 on the same class path, so the conflict cannot be resolved.

libraryA-versionX.jar


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

Relocation appears here. The class conflict is resolved by changing the package name of library A included in library B.

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 to rewrite all 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 to com.google.firebase:firebase-admin, Let’s call the library you want to avoid the conflict as 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>

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
...

com.google.guava:guava:jar:26.0-android:compileに依存しているようだ。 android用バージョンに依存しているのは気持ち悪いので、jdk用のバージョンに書き換えて、 依存関係に追加しよう。

<?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>

もう一度依存関係を確認すると以下のようになる。

$ 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
...

さて、ここからshaded-jarの設定をしていく。

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>

shade-jarを作るのには maven-shade-pluginを使う。

configurations以下が重要なので詳しく説明しよう。

<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>

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

Set relocation with <relocations>. Attach the prefix of the java package you want to relocate to <pattern>. guava.jar contains com.google.common.** and com.google.thirdparty.** So I specified com.google. On the other hand, firebase-admin contains com.google.firebase.**, Since the relocation of firebase-admin itself is not necessary, the exclusion setting is done with <excludes>.

This concludes the setting. Let’s run it to 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 classes included in guava.jar have been 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 class of firebase-admin.jar is not 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 dependencies of the included guava and firebase-admin are gone.

But there is a problem with this pom. It means that firebase-admin had other dependent libraries 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, in dependency-reduced-pom.xml, the dependencies of these libraries have been removed.

The option to solve this problem is <promoteTransitiveDependencies>. By specifying this option, all dependent libraries of firebase-admin are described as direct dependencies in dependency-reduced-pom.xml, and then firebase-admin and guava are removed. ..

Therefore, the dependencies of the libraries not included in the package 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 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>

Dependent library of firebase-admin remains correct.After that, upload this jar and dependency-reduced-pom.xml to the internal maven repository.

References

Apache Maven Shade Plugin