これは、なにをしたくて書いたもの?
Maven Shade Pluginを使うと、依存関係を含めたアーティファクトをUber JARにパッケージングすることができます。
で、設定する時にResource Transformerをなんとなく使っていたので、今回ちゃんと見てみようかなぁという気になりまして。
Resource Transformer?
Resource Transformerとは、複数のアーティファクトやライブラリを集約する際に、重複するリソースをマージするための
方法を提供するものです。
一覧はここに載っています。
Apache Maven Shade Plugin – Resource Transformers
ざっと載せると、こんな感じですね。
- ApacheLicenseResourceTransformer … ライセンスの重複を防ぐ
- ApacheNoticeResourceTransformer … NOTICEファイルの集約
- AppendingTransformer … 指定の名前のファイルの内容をひとつに集約する
- ComponentsXmlResourceTransformer …
META-INF/plexus/components.xml
ファイルをマージする - DontIncludeResourceTransformer … 指定されたルールに合致するファイルが含まれないようにする
- GroovyResourceTransformer … Apache Groovyによる拡張モジュールファイル(
META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
)をマージする - IncludeResourceTransformer … 指定したリソースを追加する
- ManifestResourceTransformer …
MANIFEST
を設定する - PluginXmlResourceTransformer … Maven Plugin Descriptorを再配置する
- ResourceBundleAppendingTransformer … 指定された
ResourceBundle
をマージする - ServicesResourceTransformer …
META-INF/services/
配下にあるService Loaderによりロードするファイルをマージする - XmlAppendingTransformer … 指定されたXMLファイルをマージする
- PropertiesTransformer … 指定のプロパティファイルをマージする
- OpenWebBeansPropertiesTransformer … Apache OpenWebBeansの設定ファイルをマージする
- MicroprofileConfigTransformer … 指定されたMicroProfile Configで使う設定ファイルをマージする
ソースコード自体は、こちらにあります。
とまあ、説明を読んでいるとどんなことができそうなのか雰囲気はわかるのですが、少しは使ってみましょうか。
お題
こちらのネタを流用して、Maven Shade Pluginを使ってUber JARを作ろうと思います。
RESTEasy+Vert.x(Handler)で遊ぶ - CLOVER🍀
ソースコードの内容は、もうちょっとシンプルにします。
この時に、Resource Transformerをいくつか使ってみましょう。
環境
今回の環境は、こちら。
$ java --version openjdk 11.0.9.1 2020-11-04 OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.20.04) OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.20.04, mixed mode, sharing) $ mvn --version Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 11.0.9.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "5.4.0-54-generic", arch: "amd64", family: "unix"
準備
Maven依存関係は、これだけ設定。
<dependencies> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-vertx</artifactId> <version>4.5.8.Final</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-reactor</artifactId> <version>4.5.8.Final</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson2-provider</artifactId> <version>4.5.8.Final</version> </dependency> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-core</artifactId> <version>3.9.4</version> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-core</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> <version>2.0.SP1</version> </dependency> </dependencies>
ソースコードはこちら。ちょっと強引に、Jackson 2とReactorを使います。
src/main/java/org/littlewings/maven/shade/App.java
package org.littlewings.maven.shade; import io.vertx.core.Vertx; import io.vertx.core.http.HttpServer; import org.jboss.logging.Logger; import org.jboss.resteasy.plugins.server.vertx.VertxRequestHandler; import org.jboss.resteasy.plugins.server.vertx.VertxResteasyDeployment; import org.jboss.resteasy.spi.ResteasyDeployment; public class App { public static void main(String... args) { Logger logger = Logger.getLogger(App.class); Vertx vertx = Vertx.vertx(); HttpServer server = vertx.createHttpServer(); ResteasyDeployment deployment = new VertxResteasyDeployment(); deployment.start(); deployment.getRegistry().addPerRequestResource(EchoResource.class); server.requestHandler(new VertxRequestHandler(vertx, deployment)); int port = 8080; server.listen(port); logger.infof("startup, server[%d]", port); } }
src/main/java/org/littlewings/maven/shade/EchoResource.java
package org.littlewings.maven.shade; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import reactor.core.publisher.Mono; @Path("echo") public class EchoResource { @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public Mono<MessageResponse> echo(MessageRequest request) { String message = request.getMessage(); String responseMessage = String.format("reply: %s", message); return Mono.just(new MessageResponse(responseMessage)); } public static class MessageRequest { String message; public String getMessage() { return message; } } public static class MessageResponse { String message; public MessageResponse(String message) { this.message = message; } public String getMessage() { return message; } } }
起動。
$ mvn compile exec:java -Dexec.mainClass=org.littlewings.maven.shade.App
動作確認。
$ curl -i -H 'Content-Type: application/json' localhost:8080/echo -d '{"message": "Hello World!!"}' HTTP/1.1 200 OK transfer-encoding: chunked Content-Type: application/json {"message":"reply: Hello World!!"}
このアプリケーションを、Maven Shade PluginでUber JARにしていきます。
Maven Shade Pluginを設定する
なにはともあれということで、Maven Shade Pluginをまずは設定します。
<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> </execution> </executions> </configuration> </plugin> </plugins> </build>
パッケージングします。
$ mvn package
すると、target
ディレクトリ配下に生成されるJARファイルが、Uber JARになります。
$ ll -h target/maven-shade-plugin-example-0.1.jar -rw-rw-r-- 1 xxxxx xxxxx 14M 11月 22 23:04 target/maven-shade-plugin-example-0.1.jar
起動には、main
メソッドを持ったクラスの指定が必要です。
$ java -cp target/maven-shade-plugin-example-0.1.jar org.littlewings.maven.shade.App 11月 22, 2020 11:05:55 午後 org.littlewings.maven.shade.App main INFO: startup, server[8080]
実は、オリジナルのJARファイルを置き換えるようにメッセージが出ているので
[INFO] Replacing original artifact with shaded artifact. [INFO] Replacing /path/to/target/maven-shade-plugin-example-0.1.jar with /path/to/target/maven-shade-plugin-example-0.1-shaded.jar
オリジナルのJARファイルを残すようにしてみましょうか。
configuration
で、shadedArtifactAttached
をtrue
に指定します。
<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> </execution> </executions> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> </configuration> </plugin>
パッケージング。
$ mvn clean package
こうすると、オリジナルのJARファイルが残り、Maven Shade PluginによるUber JARはshaded
classierが付いた状態で
作成されます。
$ ll target/*.jar -rw-rw-r-- 1 xxxxx xxxxx 13668491 11月 22 23:07 target/maven-shade-plugin-example-0.1-shaded.jar -rw-rw-r-- 1 xxxxx xxxxx 5395 11月 22 23:07 target/maven-shade-plugin-example-0.1.jar
このshaded
というのは、shadedClassifierName
で変更可能です。
<configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>uber-jar</shadedClassifierName> </configuration>
生成される名前については、outputFile
、shadedArtifactId
、finalName
など設定可能なものがいくつかあるので、詳しくは
shade:shade
ゴールのドキュメントを参照。
Apache Maven Shade Plugin – shade:shade
以降は、以下の状態からconfiguration
の中を変更していきます。
<configuration> <shadedArtifactAttached>true</shadedArtifactAttached> </configuration>
ManifestResourceTransformerでMANIFESTの設定を行う
最初に、main
クラスを指定していたのをなんとかしましょう。ManifestResourceTransformer
を使用します。
Setting Manifest Entries with the ManifestResourceTransformer
こちらにも、ほぼ同等のことが書かれています。
Apache Maven Shade Plugin – Executable JAR
こんな感じで。
<configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>org.littlewings.maven.shade.App</Main-Class> </manifestEntries> </transformer> </transformers> </configuration>
これで、Main-Class
を指定するとMETA-INF/MANIFEST.MF
に指定したクラスが設定されます。
MANIFEST.MF
の中身を確認。
$ unzip -p target/maven-shade-plugin-example-0.1-shaded.jar META-INF/MANIFEST.MF Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven 3.6.3 Built-By: kazuhira Build-Jdk: 11.0.9.1 Main-Class: org.littlewings.maven.shade.App
パッケージングして起動確認。
$ java -jar target/maven-shade-plugin-example-0.1-shaded.jar 11月 22, 2020 11:25:22 午後 org.littlewings.maven.shade.App main INFO: startup, server[8080]
java -jar
で起動できるようになりました。
ServicesResourceTransformerを使って、META-INF/servicesの中身をマージする
ところで、現状だとJARファイルを実行してもうまく動きません。
$ curl -i -H 'Content-Type: application/json' localhost:8080/echo -d '{"message": "Hello World!!"}' HTTP/1.1 415 Unsupported Media Type transfer-encoding: chunked
Content-Type
に対応したMessageBodyReader
がないと言っています。
11月 22, 2020 11:26:56 午後 org.jboss.resteasy.core.ExceptionHandler handleWebApplicationException ERROR: RESTEASY002010: Failed to execute javax.ws.rs.NotSupportedException: RESTEASY003200: Could not find message body reader for type: class org.littlewings.maven.shade.EchoResource$MessageRequest of content type: application/json at org.jboss.resteasy.core.interception.jaxrs.ServerReaderInterceptorContext.throwReaderNotFound(ServerReaderInterceptorContext.java:55) at org.jboss.resteasy.core.interception.jaxrs.AbstractReaderInterceptorContext.getReader(AbstractReaderInterceptorContext.java:133) at org.jboss.resteasy.core.interception.jaxrs.AbstractReaderInterceptorContext.proceed(AbstractReaderInterceptorContext.java:75)
パッケージングする時に実はこんな感じで大量にWARNINGが出力されていて、Uber JARを作るために各アーティファクト、
ライブラリをまとめる時にファイルが重複しているものがあると言っています。
[WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [WARNING] asyncutil-0.1.0.jar, btf-1.3.jar, cdi-api-2.0.SP1.jar, commons-codec-1.13.jar, commons-io-2.5.jar, commons-logging-1.2.jar, httpclient-4.5.12.jar, httpcore-4.4.13.jar, istack-commons-runtime-3.0.10.jar, jackson-annotations-2.11.1.jar, jackson-core-2.11.1.jar, jackson-coreutils-2.0.jar, jackson-databind-2.11.1.jar, jackson-jaxrs-base-2.11.1.jar, jackson-jaxrs-json-provider-2.11.1.jar, jackson-module-jaxb-annotations-2.11.1.jar, jakarta.activation-1.2.1.jar, jakarta.activation-api-1.2.1.jar, jakarta.validation-api-2.0.2.jar, javax.el-api-3.0.0.jar, javax.interceptor-api-1.2.jar, jaxb-runtime-2.3.3-b02.jar, jboss-annotations-api_1.3_spec-2.0.1.Final.jar, jboss-jaxb-api_2.3_spec-1.0.1.Final.jar, jboss-jaxrs-api_2.1_spec-2.0.1.Final.jar, jboss-logging-3.3.2.Final.jar, json-patch-1.13.jar, maven-shade-plugin-example-0.1.jar, microprofile-config-api-1.4.jar, microprofile-context-propagation-api-1.0-RC1.jar, msg-simple-1.2.jar, netty-buffer-4.1.49.Final.jar, netty-codec-4.1.49.Final.jar, netty-codec-dns-4.1.49.Final.jar, netty-codec-http-4.1.49.Final.jar, netty-codec-http2-4.1.49.Final.jar, netty-codec-socks-4.1.49.Final.jar, netty-common-4.1.49.Final.jar, netty-handler-4.1.49.Final.jar, netty-handler-proxy-4.1.49.Final.jar, netty-resolver-4.1.49.Final.jar, netty-resolver-dns-4.1.49.Final.jar, netty-transport-4.1.49.Final.jar, reactive-streams-1.0.3.jar, reactor-core-3.4.0.jar, resteasy-client-4.5.8.Final.jar, resteasy-client-api-4.5.8.Final.jar, resteasy-context-propagation-4.5.8.Final.jar, resteasy-core-4.5.8.Final.jar, resteasy-core-spi-4.5.8.Final.jar, resteasy-jackson2-provider-4.5.8.Final.jar, resteasy-jaxb-provider-4.5.8.Final.jar, resteasy-reactor-4.5.8.Final.jar, resteasy-vertx-4.5.8.Final.jar, smallrye-config-1.6.1.jar, smallrye-config-common-1.6.1.jar, smallrye-context-propagation-1.0.1.jar, smallrye-context-propagation-api-1.0.1.jar, txw2-2.3.3-b02.jar, vertx-core-3.9.4.jar define 1 overlapping resource: [WARNING] - META-INF/MANIFEST.MF [WARNING] istack-commons-runtime-3.0.10.jar, jakarta.activation-1.2.1.jar, jakarta.activation-api-1.2.1.jar, jaxb-runtime-2.3.3-b02.jar, jboss-annotations-api_1.3_spec-2.0.1.Final.jar, jboss-jaxrs-api_2.1_spec-2.0.1.Final.jar, txw2-2.3.3-b02.jar define 2 overlapping resources: [WARNING] - META-INF/LICENSE.md [WARNING] - META-INF/NOTICE.md [WARNING] cdi-api-2.0.SP1.jar, commons-codec-1.13.jar, commons-io-2.5.jar, commons-logging-1.2.jar, javax.el-api-3.0.0.jar, javax.interceptor-api-1.2.jar, jboss-jaxb-api_2.3_spec-1.0.1.Final.jar, jboss-logging-3.3.2.Final.jar define 1 overlapping resource: [WARNING] - META-INF/LICENSE.txt [WARNING] btf-1.3.jar, httpclient-4.5.12.jar, httpcore-4.4.13.jar, jackson-annotations-2.11.1.jar, jackson-core-2.11.1.jar, jackson-coreutils-2.0.jar, jackson-databind-2.11.1.jar, jackson-jaxrs-base-2.11.1.jar, jackson-jaxrs-json-provider-2.11.1.jar, jackson-module-jaxb-annotations-2.11.1.jar, jboss-jaxb-api_2.3_spec-1.0.1.Final.jar, json-patch-1.13.jar, microprofile-config-api-1.4.jar, msg-simple-1.2.jar define 1 overlapping resource: [WARNING] - META-INF/LICENSE [WARNING] jakarta.activation-1.2.1.jar, jakarta.activation-api-1.2.1.jar define 31 overlapping classes: [WARNING] - javax.activation.ActivationDataFlavor [WARNING] - javax.activation.CommandInfo [WARNING] - javax.activation.CommandInfo$Beans [WARNING] - javax.activation.CommandInfo$Beans$1 [WARNING] - javax.activation.CommandMap [WARNING] - javax.activation.CommandObject [WARNING] - javax.activation.DataContentHandler [WARNING] - javax.activation.DataContentHandlerFactory [WARNING] - javax.activation.DataHandler [WARNING] - javax.activation.DataHandler$1 [WARNING] - 21 more... [WARNING] resteasy-client-4.5.8.Final.jar, resteasy-context-propagation-4.5.8.Final.jar, resteasy-core-4.5.8.Final.jar, resteasy-jackson2-provider-4.5.8.Final.jar, resteasy-jaxb-provider-4.5.8.Final.jar, resteasy-reactor-4.5.8.Final.jar define 1 overlapping resource: [WARNING] - META-INF/services/javax.ws.rs.ext.Providers [WARNING] httpclient-4.5.12.jar, httpcore-4.4.13.jar, jackson-core-2.11.1.jar, jackson-databind-2.11.1.jar, jackson-jaxrs-json-provider-2.11.1.jar, jackson-module-jaxb-annotations-2.11.1.jar, microprofile-config-api-1.4.jar define 1 overlapping resource: [WARNING] - META-INF/NOTICE [WARNING] httpclient-4.5.12.jar, httpcore-4.4.13.jar define 1 overlapping resource: [WARNING] - META-INF/DEPENDENCIES [WARNING] commons-codec-1.13.jar, commons-io-2.5.jar, commons-logging-1.2.jar define 1 overlapping resource: [WARNING] - META-INF/NOTICE.txt [WARNING] btf-1.3.jar, jackson-coreutils-2.0.jar, json-patch-1.13.jar, msg-simple-1.2.jar define 2 overlapping resources: [WARNING] - META-INF/ASL-2.0.txt [WARNING] - META-INF/LGPL-3.0.txt [WARNING] netty-common-4.1.49.Final.jar, reactor-core-3.4.0.jar define 1 overlapping resource: [WARNING] - META-INF/services/reactor.blockhound.integration.BlockHoundIntegration [WARNING] netty-buffer-4.1.49.Final.jar, netty-codec-4.1.49.Final.jar, netty-codec-dns-4.1.49.Final.jar, netty-codec-http-4.1.49.Final.jar, netty-codec-http2-4.1.49.Final.jar, netty-codec-socks-4.1.49.Final.jar, netty-common-4.1.49.Final.jar, netty-handler-4.1.49.Final.jar, netty-handler-proxy-4.1.49.Final.jar, netty-resolver-4.1.49.Final.jar, netty-resolver-dns-4.1.49.Final.jar, netty-transport-4.1.49.Final.jar define 1 overlapping resource: [WARNING] - META-INF/io.netty.versions.properties [WARNING] maven-shade-plugin has detected that some class files are [WARNING] present in two or more JARs. When this happens, only one [WARNING] single version of the class is copied to the uber jar. [WARNING] Usually this is not harmful and you can skip these warnings, [WARNING] otherwise try to manually exclude artifacts based on [WARNING] mvn dependency:tree -Ddetail=true and the above output. [WARNING] See http://maven.apache.org/plugins/maven-shade-plugin/
で、今回は特にこれが問題になっていますね。
[WARNING] resteasy-client-4.5.8.Final.jar, resteasy-context-propagation-4.5.8.Final.jar, resteasy-core-4.5.8.Final.jar, resteasy-jackson2-provider-4.5.8.Final.jar, resteasy-jaxb-provider-4.5.8.Final.jar, resteasy-reactor-4.5.8.Final.jar define 1 overlapping resource: [WARNING] - META-INF/services/javax.ws.rs.ext.Providers
マージ後はどうなっているんでしょう?
$ unzip -p target/maven-shade-plugin-example-0.1-shaded.jar META-INF/services/javax.ws.rs.ext.Providers org.jboss.resteasy.client.jaxrs.internal.CompletionStageRxInvokerProvider
ひとつだけ残っています…。
ここで、ServicesResourceTransformer
を使います。
Concatenating Service Entries with the ServicesResourceTransformer
<configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>org.littlewings.maven.shade.App</Main-Class> </manifestEntries> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> </configuration>
JARファイルを再度作成して起動。
$ java -jar target/maven-shade-plugin-example-0.1-shaded.jar 11月 22, 2020 11:37:36 午後 org.littlewings.maven.shade.App main INFO: startup, server[8080]
確認。
$ curl -i -H 'Content-Type: application/json' localhost:8080/echo -d '{"message": "Hello World!!"}' HTTP/1.1 200 OK transfer-encoding: chunked Content-Type: application/json {"message":"reply: Hello World!!"}
今度はOKでした。
マージ後のファイルはどうなったんでしょう?
$ unzip -p target/maven-shade-plugin-example-0.1-shaded.jar META-INF/services/javax.ws.rs.ext.Providers org.jboss.resteasy.client.jaxrs.internal.CompletionStageRxInvokerProvider org.jboss.resteasy.plugins.providers.AsyncStreamingOutputProvider org.jboss.resteasy.plugins.providers.DataSourceProvider org.jboss.resteasy.plugins.providers.DocumentProvider org.jboss.resteasy.plugins.providers.DefaultTextPlain org.jboss.resteasy.plugins.providers.DefaultNumberWriter org.jboss.resteasy.plugins.providers.DefaultBooleanWriter org.jboss.resteasy.plugins.providers.StringTextStar org.jboss.resteasy.plugins.providers.SourceProvider org.jboss.resteasy.plugins.providers.InputStreamProvider org.jboss.resteasy.plugins.providers.ReaderProvider org.jboss.resteasy.plugins.providers.ByteArrayProvider org.jboss.resteasy.plugins.providers.FormUrlEncodedProvider org.jboss.resteasy.plugins.providers.JaxrsFormProvider org.jboss.resteasy.plugins.providers.CompletionStageProvider org.jboss.resteasy.plugins.providers.ReactiveStreamProvider org.jboss.resteasy.plugins.providers.FileProvider org.jboss.resteasy.plugins.providers.FileRangeWriter org.jboss.resteasy.plugins.providers.StreamingOutputProvider org.jboss.resteasy.plugins.providers.IIOImageProvider org.jboss.resteasy.plugins.providers.MultiValuedParamConverterProvider org.jboss.resteasy.plugins.interceptors.CacheControlFeature org.jboss.resteasy.plugins.interceptors.ClientContentEncodingAnnotationFeature org.jboss.resteasy.plugins.interceptors.ServerContentEncodingAnnotationFeature org.jboss.resteasy.plugins.interceptors.MessageSanitizerContainerResponseFilter org.jboss.resteasy.plugins.providers.sse.SseEventProvider org.jboss.resteasy.plugins.providers.sse.SseEventSinkInterceptor org.jboss.resteasy.reactor.MonoProvider org.jboss.resteasy.reactor.MonoRxInvokerImpl org.jboss.resteasy.reactor.MonoRxInvokerProvider org.jboss.resteasy.reactor.FluxProvider org.jboss.resteasy.reactor.FluxRxInvokerImpl org.jboss.resteasy.reactor.FluxRxInvokerProvider org.jboss.resteasy.context.ContextFeature org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider org.jboss.resteasy.plugins.providers.jackson.UnrecognizedPropertyExceptionHandler org.jboss.resteasy.plugins.providers.jackson.PatchMethodFilter org.jboss.resteasy.plugins.providers.jaxb.JAXBXmlSeeAlsoProvider org.jboss.resteasy.plugins.providers.jaxb.JAXBXmlRootElementProvider org.jboss.resteasy.plugins.providers.jaxb.JAXBElementProvider org.jboss.resteasy.plugins.providers.jaxb.JAXBXmlTypeProvider org.jboss.resteasy.plugins.providers.jaxb.CollectionProvider org.jboss.resteasy.plugins.providers.jaxb.MapProvider org.jboss.resteasy.plugins.providers.jaxb.XmlJAXBContextFinder
めちゃくちゃ増えました…。
PropertiesTransformerでプロパティファイルをマージする
WARNINGを見ていると、プロパティファイルも重複しているようです。
[WARNING] netty-buffer-4.1.49.Final.jar, netty-codec-4.1.49.Final.jar, netty-codec-dns-4.1.49.Final.jar, netty-codec-http-4.1.49.Final.jar, netty-codec-http2-4.1.49.Final.jar, netty-codec-socks-4.1.49.Final.jar, netty-common-4.1.49.Final.jar, netty-handler-4.1.49.Final.jar, netty-handler-proxy-4.1.49.Final.jar, netty-resolver-4.1.49.Final.jar, netty-resolver-dns-4.1.49.Final.jar, netty-transport-4.1.49.Final.jar define 1 overlapping resource: [WARNING] - META-INF/io.netty.versions.properties
これを、PropertiesTransformer
を使ってマージしてみましょう。
Merging properties files with PropertiesTransformer
現時点での中身を確認。
$ unzip -p target/maven-shade-plugin-example-0.1-shaded.jar META-INF/io.netty.versions.properties #Generated by netty-parent/pom.xml #Wed, 22 Apr 2020 10:53:19 +0000 netty-common.version=4.1.49.Final netty-common.buildDate=2020-04-22 10\:53\:19 +0000 netty-common.commitDate=2020-04-22 09\:57\:26 +0000 netty-common.shortCommitHash=d0ec961 netty-common.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-common.repoStatus=clean
PropertiesTransformer
を設定。
<configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>org.littlewings.maven.shade.App</Main-Class> </manifestEntries> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> <transformer implementation="org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer"> <resource>META-INF/io.netty.versions.properties</resource> <alreadyMergedKey>already_merged</alreadyMergedKey> </transformer> </transformers> </configuration>
パッケージングして、プロパティファイルの中身を確認。
$ unzip -p target/maven-shade-plugin-example-0.1-shaded.jar META-INF/io.netty.versions.properties # Merged by maven-shade-plugin (org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer) netty-buffer.buildDate=2020-04-22 10\:54\:59 +0000 netty-buffer.commitDate=2020-04-22 09\:57\:26 +0000 netty-buffer.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-buffer.repoStatus=clean netty-buffer.shortCommitHash=d0ec961 netty-buffer.version=4.1.49.Final netty-codec-dns.buildDate=2020-04-22 10\:59\:08 +0000 netty-codec-dns.commitDate=2020-04-22 09\:57\:26 +0000 netty-codec-dns.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-codec-dns.repoStatus=clean netty-codec-dns.shortCommitHash=d0ec961 netty-codec-dns.version=4.1.49.Final netty-codec-http.buildDate=2020-04-22 11\:04\:06 +0000 netty-codec-http.commitDate=2020-04-22 09\:57\:26 +0000 netty-codec-http.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-codec-http.repoStatus=clean netty-codec-http.shortCommitHash=d0ec961 netty-codec-http.version=4.1.49.Final netty-codec-http2.buildDate=2020-04-22 11\:04\:52 +0000 netty-codec-http2.commitDate=2020-04-22 09\:57\:26 +0000 netty-codec-http2.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-codec-http2.repoStatus=clean netty-codec-http2.shortCommitHash=d0ec961 netty-codec-http2.version=4.1.49.Final netty-codec-socks.buildDate=2020-04-22 11\:06\:56 +0000 netty-codec-socks.commitDate=2020-04-22 09\:57\:26 +0000 netty-codec-socks.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-codec-socks.repoStatus=clean netty-codec-socks.shortCommitHash=d0ec961 netty-codec-socks.version=4.1.49.Final netty-codec.buildDate=2020-04-22 10\:58\:33 +0000 netty-codec.commitDate=2020-04-22 09\:57\:26 +0000 netty-codec.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-codec.repoStatus=clean netty-codec.shortCommitHash=d0ec961 netty-codec.version=4.1.49.Final netty-common.buildDate=2020-04-22 10\:53\:19 +0000 netty-common.commitDate=2020-04-22 09\:57\:26 +0000 netty-common.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-common.repoStatus=clean netty-common.shortCommitHash=d0ec961 netty-common.version=4.1.49.Final netty-handler-proxy.buildDate=2020-04-22 11\:07\:55 +0000 netty-handler-proxy.commitDate=2020-04-22 09\:57\:26 +0000 netty-handler-proxy.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-handler-proxy.repoStatus=clean netty-handler-proxy.shortCommitHash=d0ec961 netty-handler-proxy.version=4.1.49.Final netty-handler.buildDate=2020-04-22 11\:00\:05 +0000 netty-handler.commitDate=2020-04-22 09\:57\:26 +0000 netty-handler.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-handler.repoStatus=clean netty-handler.shortCommitHash=d0ec961 netty-handler.version=4.1.49.Final netty-resolver-dns.buildDate=2020-04-22 11\:08\:26 +0000 netty-resolver-dns.commitDate=2020-04-22 09\:57\:26 +0000 netty-resolver-dns.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-resolver-dns.repoStatus=clean netty-resolver-dns.shortCommitHash=d0ec961 netty-resolver-dns.version=4.1.49.Final netty-resolver.buildDate=2020-04-22 10\:56\:46 +0000 netty-resolver.commitDate=2020-04-22 09\:57\:26 +0000 netty-resolver.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-resolver.repoStatus=clean netty-resolver.shortCommitHash=d0ec961 netty-resolver.version=4.1.49.Final netty-transport.buildDate=2020-04-22 10\:57\:08 +0000 netty-transport.commitDate=2020-04-22 09\:57\:26 +0000 netty-transport.longCommitHash=d0ec961cce19646519d6a0d59e7604b0eacd9bf2 netty-transport.repoStatus=clean netty-transport.shortCommitHash=d0ec961 netty-transport.version=4.1.49.Final
めちゃくちゃ増えました…。
ライセンスの破棄やNOTICEのマージ
最後に、ライブラリに含まれているLICENSE
およびLICENSE.txt
を破棄して
[WARNING] cdi-api-2.0.SP1.jar, commons-codec-1.13.jar, commons-io-2.5.jar, commons-logging-1.2.jar, javax.el-api-3.0.0.jar, javax.interceptor-api-1.2.jar, jboss-jaxb-api_2.3_spec-1.0.1.Final.jar, jboss-logging-3.3.2.Final.jar define 1 overlapping resource: [WARNING] - META-INF/LICENSE.txt [WARNING] btf-1.3.jar, httpclient-4.5.12.jar, httpcore-4.4.13.jar, jackson-annotations-2.11.1.jar, jackson-core-2.11.1.jar, jackson-coreutils-2.0.jar, jackson-databind-2.11.1.jar, jackson-jaxrs-base-2.11.1.jar, jackson-jaxrs-json-provider-2.11.1.jar, jackson-module-jaxb-annotations-2.11.1.jar, jboss-jaxb-api_2.3_spec-1.0.1.Final.jar, json-patch-1.13.jar, microprofile-config-api-1.4.jar, msg-simple-1.2.jar define 1 overlapping resource: [WARNING] - META-INF/LICENSE
Preventing License Duplication with the ApacheLicenseResourceTransformer
NOTICEファイルをマージします。
[WARNING] httpclient-4.5.12.jar, httpcore-4.4.13.jar, jackson-core-2.11.1.jar, jackson-databind-2.11.1.jar, jackson-jaxrs-json-provider-2.11.1.jar, jackson-module-jaxb-annotations-2.11.1.jar, microprofile-config-api-1.4.jar define 1 overlapping resource: [WARNING] - META-INF/NOTICE [WARNING] commons-codec-1.13.jar, commons-io-2.5.jar, commons-logging-1.2.jar define 1 overlapping resource: [WARNING] - META-INF/NOTICE.txt
Aggregating Notices with the ApacheNoticeResourceTransformer
設定。
<configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>org.littlewings.maven.shade.App</Main-Class> </manifestEntries> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> <transformer implementation="org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer"> <resource>META-INF/io.netty.versions.properties</resource> <alreadyMergedKey>already_merged</alreadyMergedKey> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer"> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer"> <addHeader>false</addHeader> </transformer> </transformers> </configuration>
これで、LICENSE.txt
およびLICENSE
ファイルがなくなります。
$ unzip -l target/maven-shade-plugin-example-0.1-shaded.jar | grep LICENSE 35084 2019-06-16 21:23 META-INF/LICENSE.md
.md
の方が残っていますが…。
NOTICE
ファイルは、マージされます。
$ unzip -p target/maven-shade-plugin-example-0.1-shaded.jar META-INF/NOTICE Apache Commons IO Copyright 2002-2016 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). ========================================================================= == NOTICE file corresponding to section 4(d) of the Apache License, == == Version 2.0, in this case for Microprofile Config == ========================================================================= Portions of this software were originally based on the following: * Apache DeltaSpike Config https://deltaspike.apache.org under Apache License, v2.0 SPDXVersion: SPDX-2.1 PackageName: Eclipse Microprofile PackageHomePage: http://www.eclipse.org/microprofile PackageLicenseDeclared: Apache-2.0 PackageCopyrightText: <text> Mark Struberg struberg@apache.org, Gerhard Petracek gpetracek@apache.org, Romain Manni-Bucau rmannibucau@apache.org, Ron Smeral rsmeral@apache.org, Emily Jiang emijiang@uk.ibm.com, Ondrej Mihalyi ondrej.mihalyi@gmail.com, Gunnar Morling gunnar@hibernate.org </text> Apache HttpClient Copyright 1999-2020 The Apache Software Foundation Apache HttpCore Copyright 2005-2020 The Apache Software Foundation Apache Commons Logging Copyright 2003-2014 The Apache Software Foundation Apache Commons Codec Copyright 2002-2019 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (https://www.apache.org/). src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java contains test data from http://aspell.net/test/orig/batch0.tab. Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org) =============================================================================== The content of package org.apache.commons.codec.language.bm has been translated from the original php source code available at http://stevemorse.org/phoneticinfo.htm with permission from the original authors. Original source copyright: Copyright (c) 2008 Alexander Beider & Stephen P. Morse. # Jackson JSON processor Jackson is a high-performance, Free/Open Source JSON processing library. It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has been in development since 2007. It is currently developed by a community of developers, as well as supported commercially by FasterXML.com. ## Licensing Jackson core and extension components may licensed under different licenses. To find the details that apply to this artifact see the accompanying LICENSE file. For more information, including possible other licensing options, contact FasterXML.com (http://fasterxml.com). ## Credits A list of contributors may be found from CREDITS file, which is included in some artifacts (usually source distributions); but is always available from the source code management (SCM) system project uses. Jackson core and extension components may be licensed under different licenses. To find the details that apply to this artifact see the accompanying LICENSE file. For more information, including possible other licensing options, contact FasterXML.com (http://fasterxml.com).
今回は、ざっとこんな感じで。
まとめ
これまでMaven Shade Pluginをそれほど使っていなかったというのと、使っても雰囲気でコピー&ペーストしていてあまり
ちゃんと見ていなかったので、これを機に見てみてだいぶ雰囲気わかった気がします。
今後は、もうちょっとちゃんと使いましょう…。
最後に、今回のMaven Shade Pluginの設定全体を載せておきます。
<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> </execution> </executions> <configuration> <shadedArtifactAttached>true</shadedArtifactAttached> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>org.littlewings.maven.shade.App</Main-Class> </manifestEntries> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> <transformer implementation="org.apache.maven.plugins.shade.resource.properties.PropertiesTransformer"> <resource>META-INF/io.netty.versions.properties</resource> <alreadyMergedKey>already_merged</alreadyMergedKey> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer"> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer"> <addHeader>false</addHeader> </transformer> </transformers> </configuration> </plugin>