概要
Maven の provided スコープのような、「コンパイル時には含めるが Jar には入れない」という依存を記述したかったので、どうやるか調べてみました。
目的
あるアプリケーションAに別のアプリケーションBのコードをjarにして同梱する際、BのjarにAでも利用しているライブラリが入っていると、Aをfat jarにした際に重複してしまって無駄が発生するので、B の依存解決で provided スコープでの依存指定ができるようにしたい、という事情がありました。
------------A----------- ------------B-----------
| lib:lib.commons:0.0.1 | | lib:lib.commons:0.0.1 | <---この lib.commons-0.0.1 を B.jar から除外したい
| B.jar | ------------------------
------------------------
作業環境
Java SE | 1.8.0_102 |
---|---|
OS | Windows 10 |
Gradle | 3.0 |
作業
provided
まず configurations ブロックで provided を宣言しておきます。
configurations {
provided
}
依存の記述
続いて、dependencies で provided の依存を記述します。
dependencies {
provided 'com.jfoenix:jfoenix:1.0.0'
provided 'org.slf4j:slf4j-api:1.7.21'
provided 'org.slf4j:slf4j-log4j12:1.7.21'
……
compileJava の記述
provided をコンパイルのクラスパスに含めます。
compileJava {
sourceSets.main.compileClasspath += configurations.provided
sourceSets.test.compileClasspath += configurations.provided
}
テストのクラスパスに追加
忘れるとテスト実行時に大量の java.lang.NoClassDefFoundError
が出ます。
test {
classpath += configurations.provided
}
(任意) application プラグインを使っている場合
run にも入れておきます。
run {
classpath += configurations.provided
}
(任意) Eclipse 上で依存解決したい場合
下記を追加してください。
apply plugin: 'eclipse'
……
eclipse {
classpath {
plusConfigurations += [ configurations.provided ]
}
}
参考
jar タスクの修正
compile のものだけ jar に含めるように指定します。
jar {
……
from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
……
実践
今回は JVM 言語のスクリプトを実行するアプリケーション のコードを使って試してみます。
(共通) jar生成
修正前後で同じコマンドを使います。
$ gradle clean jar
Starting a Gradle Daemon, 1 busy Daemon could not be reused, use --status for details
:clean
:compileJava
:processResources
:classes
:jar
BUILD SUCCESSFUL
Total time: 12.758 secs
修正前
jar のサイズは 24.58MB、jar のファイル数は 15,850 でした。
$ ls -l ScriptRunner-0.0.1.jar
-rw-r--r-- 1 John Kay 197121 24580947 Oct 30 15:31 ScriptRunner-0.0.1.jar
$ ls -lh ScriptRunner-0.0.1.jar
-rw-r--r-- 1 John Kay 197121 24M Oct 30 15:31 ScriptRunner-0.0.1.jar
$ jar tf ScriptRunner-0.0.1_.jar | wc -l
15850
修正
jar に含めない依存を compile から provided に変更します。
修正後
$ gradle clean jar
で jar を作り直します。
$ ls -l ScriptRunner-0.0.1.jar
-rw-r--r-- 1 John Kay 197121 10647049 Oct 30 15:34 ScriptRunner-0.0.1.jar
$ ls -lh ScriptRunner-0.0.1.jar
-rw-r--r-- 1 John Kay 197121 11M Oct 30 15:34 ScriptRunner-0.0.1.jar
$ jar tf ScriptRunner-0.0.1.jar | wc -l
8018
生成された jar はファイルサイズが 10.647MB、ファイル数が 8,018 でした。確実に小さくなっているのがわかります。
まとめ
プラグイン等は必要なく、 Gradle 標準の仕組みだけで、 Maven の provided スコープのような依存指定ができました。フレームワークの依存が必要なアプリケーション開発(Storm等)で使えると思います。