概要
以前こんな記事を書いた。
Android Studio 3にしたらJavaアプリケーションの依存関係が解決できなくなったのでその対処方法
この記事の方法はスマートではなかったため、再チャレンジしたら良い方法を発見できた。
構成
- MyApplicationという名前のプロジェクトがある。
- MyApplicationにはappというモジュール(Androidアプリ)がある。
- MyApplicationにはpurejavaというモジュール(Javaアプリ)がある。(このモジュールを単体で実行すると依存関係が解決できない)
それぞれのbuild.gradle
はこんな感じ
./MyApplication/purejava/build.gradle
./MyApplication/app/build.gradle
./MyApplication/build.gradle
方法
まず、適用したいモジュールのbuild.gradleにapply plugin: 'idea'
を追加する。
今回は例としてGsonを追加している。それ以外はデフォルトで自動生成されたやつ。
apply plugin: 'java-library'
apply plugin: 'idea' //これ
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.google.code.gson:gson:2.8.2'
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
もしくは、ルートのbuild.gradleに追記することで全モジュールに一度に適用することもできる。
allprojects {
apply plugin: 'idea'
}
次にApplicationのConfigurationをデフォルトで作り、Before launchにRun Gradle taskからideaというtaskを追加する。
これでここから依存関係を解決した状態で実行できる。
Debugで実行すればもちろんブレークポイントで止まることも可能。
結果
purejavaモジュールの適当なクラスでGsonを使うと、
public class MyClass {
public MyClass() {
String jsonString = "{\"a\": 12345, \"b\": 67890}";
JsonObject jsonObject = new JsonParser().parse(jsonString).getAsJsonObject();
System.out.println("aは " + jsonObject.get("a"));
System.out.println("bは " + jsonObject.get("b"));
}
public static void main(String[] args) throws Exception {
new MyClass();
}
}
ちゃんと使えててハッピー
aは 12345
bは 67890
なぜか
Sync Project with Gradle Filesすると**.iml**が更新される。
.imlを見ると、例えばGsonがdependenciesにあれば、こういうorderEntryが生成されている。
<orderEntry type="library" exported="" scope="PROVIDED" name="gson-2.8.2" level="project" />
ここで悪さをしているのはscope="PROVIDED"
である。
なぜなら手動でscope=""
に修正すると、上記のideaタスクを実行する必要なく、依存関係が解決できるためである。
そこで、./gradlew idea
を実行する。
その後、.imlを見てみると、Gsonのjarをフルパスで指定してくれおり、依存関係は解決される。
結論
.gradleにscopeを""に修正するようなタスクを実装する方法もあるように思うが、よく分からなかったので諦めた。
とりあえず、Android Studio 2.x時代の時と同じように、簡単にブレークポイントで止まれるような実行ができるのでとても良い。
余談
毎回ideaタスクを実行するので、実行がワンテンポ遅くなってしまう。
結局、.imlはSync Project with Gradle Filesしなければ更新されないようなので、Run Gradle taskにideaタスク無しバージョンのRun Configurationも作っておいて、普段はこっちを使って、Syncした後に手動で./gradlew idea
を実行して.imlを更新してもいいかもしれない。
もしかしてSync Project with Gradle Filesの時に追加task実行できたりする?