#navi_header|Groovy| * JavaとGroovyの混在したソースコードを扱うときの注意点 ポイント: ''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 のタスク依存関係参照。) 解決策としては以下の様な対応方法があります。 - 一番単純なのは "src/(main|test)/groovy" 以下にJavaのソースを置きます。これなら何も調整せずにGroovyコンパイラがJavaソースも同時にコンパイルしてくれます。 - ディレクトリを分離しておきたい場合は、Groovyコンパイラが参照する "SourceSet" にJavaのソースが入ってるディレクトリを追加します。 -- この場合、Javaコンパイラが参照する "SourceSet" からGroovy側で参照するJavaソースディレクトリを外しておいてください。そのままにしておくと、Javaコンパイラ側でも処理されてしまいます。 サンプル: - msakamoto-sf/gradle-java-groovy-conjunction-demo1 -- https://github.com/msakamoto-sf/gradle-java-groovy-conjunction-demo1 検証環境: - Win7 64bit - JDK7 - Gradle 1.4 ** サンプル解説 : java-refer-groovy-0 (失敗例) サンプルコード: 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" 関連のパスはどこにも出て来ません。 #pre||> 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 ||< ** サンプル解説 : java-refer-groovy-1 ("SourceSet"を調整) サンプルコード: https://github.com/msakamoto-sf/gradle-java-groovy-conjunction-demo1/tree/master/java-refer-groovy-1 build.gradleで以下のように調整し、GroovyコンパイラがJavaのソースを一緒にコンパイルしてくれるように調整してます。 #pre||> 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ソースディレクトリを外しておくのを忘れないようにします。 ** サンプル解説 : java-refer-groovy-2 ("src/main/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コンパイラ側で一緒にコンパイルしてくれます。 ** 参考 - gradle-user - Mixed groovy and java code -- http://gradle.1045684.n5.nabble.com/Mixed-groovy-and-java-code-td5001914.html --- sourceSetsの調整による対応 - gradle-user - Groovy/Java mixed codebase -- http://gradle.1045684.n5.nabble.com/Groovy-Java-mixed-codebase-td1435484.html --- sourceSetsの調整と、GroovyソースにJavaも含めてしまう対応 - gradle-user - Gradle and mixed Java/Groovy source -- http://gradle.1045684.n5.nabble.com/Gradle-and-mixed-Java-Groovy-source-td1434813.html --- JavaコンパイラはGroovyの世界を知りません、という内容。 #navi_footer|Groovy|