ポイント:JavaからGroovyを参照する時は、Groovy側と一緒にコンパイルされるようにする。
GradleではJavaコンパイラがまず実行され、続いてGroovyコンパイラ(内部的にはGroovyとJavaを一緒にコンパイルできるようになってる)が起動されます。そのため、Groovy側ソースのクラスを参照しているJavaソースがある場合、最初にJavaコンパイラが実行される時点ではGroovyのソースやクラスを認識できないため、参照先のGroovy側のパッケージやクラス名を解決出来ずエラーになります。なお、JavaのソースからGroovyを参照しておらず、あくまでもGroovyがJavaを参照しているだけであれば本記事で紹介しているような調整は不要です。
( http://www.gradle.org/docs/current/userguide/groovy_plugin.html のタスク依存関係参照。)
解決策としては以下の様な対応方法があります。
サンプル:
検証環境:
サンプルコード:
https://github.com/msakamoto-sf/gradle-java-groovy-conjunction-demo1/tree/master/java-refer-groovy-0
Groovyのクラスを "src/main/java" のクラスから参照してます。参照先のGroovy側のパッケージやクラス名を解決出来ずにエラーになります。
"gradle -d"でデバッグログを有効にしてJavaコンパイラが起動するときの引数を確認してみると、当然ですが "src/main/groovy" 関連のパスはどこにも出て来ません。
23:37:22.253 [DEBUG] [org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler] Compiler arguments: \ -d (...)/build/classes/main \ -g \ -classpath (.../.gradle/...)/groovy-all-1.8.9.jar \ (...)/java-refer-groovy-0src/main/java/j1/JavaBean.java \ (...)/java-refer-groovy-0/src/main/java/j1/Main.java
サンプルコード:
https://github.com/msakamoto-sf/gradle-java-groovy-conjunction-demo1/tree/master/java-refer-groovy-1
build.gradleで以下のように調整し、GroovyコンパイラがJavaのソースを一緒にコンパイルしてくれるように調整してます。
sourceSets.main.java.srcDirs = [] sourceSets.main.groovy.srcDirs = ['src/main/groovy', 'src/main/java'] sourceSets.test.java.srcDirs = [] sourceSets.test.groovy.srcDirs = ['src/test/groovy', 'src/test/java']
sourceSets.(main|test).java.srcDirs から、Groovy側でコンパイルさせるJavaソースディレクトリを外しておくのを忘れないようにします。
サンプルコード:
https://github.com/msakamoto-sf/gradle-java-groovy-conjunction-demo1/tree/master/java-refer-groovy-2
"src/main/groovy/" 以下にGroovyとJavaソースを配置してます。これによりJavaコンパイラは何も処理せずにスルーされ、Groovyコンパイラ側で一緒にコンパイルしてくれます。
コメント