Shaded jarとは
Javaでのdependency-hellを回避するための方法の一つ。
元々のコードベースが、ライブラリAのバージョンXに依存しているとする。
このコードベースに新たなライブラリBを追加したい。
しかしながら、ライブラリBはライブラリAのバージョンYに依存しており、
ライブラリAのバージョンXとYは互換性がないという状況を考えよう。
CodeBase
|- Library A, Version X
|- Library B
|- Library A, Version Y # Conflict!!!
このままではライブラリAのバージョンX, Yのどちらを選んでも新規機能と既存機能の
両方を同時に動かすことはできない。
ここで登場するのがshaded-jarである。
Library AのバージョンYのクラスを全てLibrary Bに同梱してしまい、依存関係を排除したライブラリB'を作成するという方法だ。
CodeBase
|- Library A, Version X
|- Library B' (include Library A, Version Y)
relocation
しかしそのままではライブラリAに含まれるクラスと、ライブラリB'に同梱したライブラリAのクラスが同じクラスパスに置かれるため、コンフリクトが解消できない。
com.foo.libraryA.Bar.class
...
com.bar.libraryB.Example.class
...
com.foo.libraryA.Bar.class # Conflict!!
...
ここで登場するのがrelocationである。
ライブラリBに同梱されるライブラリAのパッケージ名を変えることでクラスの競合を解消するのだ。
com.bar.libraryB.Example.class
...
shaded.com.foo.libraryA.Bar.class # No Conflict :)
...
この例では com.foo.libraryA
を shaded.com.foo.libraryA
に変更している。
ただリネームしているだけではなく、ライブラリBに含まれるライブラリAのクラスへの参照も全て書き換えることがポイントだ。
shaded-jarの作り方
今回の記事ではmavenを使ったやり方を説明する。
例として追加したいライブラリを com.google.firebase:firebase-admin
,
競合を回避したいライブラリを com.google.guava:guava
としよう。
まず、以下のようなpomファイルを用意する。
<?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>
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の設定をしていく。
<?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>
<artifactSet>
でshaded-jarに同梱するartifactの一覧を設定する。
今回のメインとなる、firebase-admin
と、同梱したい依存ライブラリ guava
を指定している。
<relocations>
でrelocationの設定を行う。
<pattern>
にはrelocationしたいjavaパッケージのprefixをつける。
guava.jar
の中には com.google.common.**
と com.google.thirdparty.**
が含まれている
ので com.google
を指定した。
一方で firebase-admin
には com.google.firebase.**
が含まれており、
firebase-admin
自体のrelocationは必要ないので <excludes>
で除外設定をしている。
これで設定は終わりである。実行してどのようなjarが作られるか確認しよう。
$ mvn package
target/shadeex-1.0.0.jar
にshaded-jarが出力される。
中身を確認してみると、確かに、guava.jarに含まれるクラスがrelocationされていることがわかる。
$ 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/
一方で、 firebase-admin.jar
のクラスはrelocationされていない。
$ 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
また、それ以外の依存ライブラリのクラスは同梱されない。
$ 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
はshaded-jar用の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>
同梱した guava
と firebase-admin
のdependencyが消えていることがわかるだろう。
しかし、このpomには問題がある。
それは firebase-admin
の依存ライブラリは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
しかし、dependency-reduced-pom.xml
ではこれらのライブラリのdependencyが取り除かれてしまっている。
この問題を解決するオプションが <promoteTransitiveDependencies>
である。
このオプションを指定することで、 firebase-admin
の依存ライブラリが全て、 dependency-reduced-pom.xml
の直接のdependencyとして記載され、その後、 firebase-admin
と guava
が取り除かれる。
したがって同梱しないライブラリの依存関係を正しく残すことができる。
最終的な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>
これに対して、mvn package
を実行して出力される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>
firebase-admin
の依存ライブラリが正しく残っている。
あとは このjarとdependency-reduced-pom.xml
をinternal maven repositoryにアップロードすればよい。