Android Studio 3にしたらJavaアプリケーションの依存関係が解決できなくなったのでその対処方法

# 症状
Android Studio 3.xに対応するため、`com.android.tools.build:gradle:3.0.1`に変更したところ、RunConfigurationのApplicationから実行できていたpure Javaなアプリケーションの依存が解決できなくなった。
つまり`NoClassDefFoundError`が出る。

要はあるModuleにこんなJava Application存在していた。
<img width="1000" alt="スクリーンショット 2017-12-09 20.44.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/46022/f2dc798d-72a0-33ac-ed94-65b7c2c3aa2d.png">


# 対処 (ベストプラクティスは[こちら](https://qiita.com/KoheiKanagu/items/0836d11c608d9394a36e#そしてベストプラクティス))

**注意: これだとブレークポイントで止まれない。止まることができる方法は後述**

このように、`gradle run`で実行できるように設定する。
画像ではlibというモジュール名になってる。
`:yourModuleName:run`

<img width="1000" alt="スクリーンショット 2017-12-09 20.44.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/46022/a8a0895d-1140-fb92-cf01-527304dd22f6.png">

そして、対象のmoduleのbuild.gradleに以下を追記。

```:build.gradle
apply plugin: 'application'

mainClassName = "your.main.class.myClass"
```

要はresourceが取得できなかった問題に似ている？
[Android StudioでJava Libraryなモジュールからリソースを含んだ実行可能なJarを生成するまで](https://qiita.com/KoheiKanagu/items/a04304aed15bd8944eea)


## ブレークポイントでも止まる実行方法
**注意: ブレークしてしばらくしたらgradleのtaskが死んでしまうのでダメか...**

`lib`というJavaなモジュールがあって、`myClass.java`があって、Gsonを参照しているとする。

```java:myClass.java
package com.example.lib;

import com.google.gson.GsonBuilder;

public class myClass {
    public myClass() {
        System.out.println(GsonBuilder.class);
        System.out.println("hoge");
    }
    public static void main(String[] args) throws Exception {
        new myClass();
    }
}
```

`build.gradle`にJavaExecなtaskを適当な名前で追加する。
ここで`executeHote`とか`executePiyo`とか名前を変えて、それぞれのmainを設定しておけば、mainを複数作りたいmoduleでも対応できると思う。

```:build.gradle
apply plugin: 'application'

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.google.code.gson:gson:2.8.2'
}

mainClassName = "" //意味ないように見えるが、これがないとプロジェクト全体のbuildが通らない

task executeMyClass(type: JavaExec) {
    main = "com.example.lib.myClass"
    classpath = sourceSets.main.runtimeClasspath
}
```


Add New ConfigurationからRemoteを追加。Nameは適当に。
`Search sources using module's classpath:`は`<whole project>`でのままでもいいかもしれない

Before launchのところから`Run Gradle task`を追加する。
Grade projectは実行したいprojectであり、今回はlib。
Talksには`:lib:executeMyClass --debug-jvm`とする。（`--debug-jvm`によってデバッガのアタッチを待ってくれる。）
<img width="520" alt="スクリーンショット 2017-12-10 22.16.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/46022/f701b305-3711-8fdf-d754-ffea174c6cd2.png">
まとめるとこんな感じになる。
<img width="1000" alt="スクリーンショット 2017-12-10 22.12.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/46022/060002c7-5a55-6bb8-f8da-c29574140571.png">

### 実行

Run debugをすると`Before launch`に従って`executeMyClass`が実行される。
が、これはデバッガからのアタッチを待ってるので終わらない。

なのでStopする。要は画像の一番右のやつをクリック。
<img width="323" alt="スクリーンショット 2017-12-10 22.25.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/46022/d51db227-16a3-3c8b-4604-95b393eee0c3.png">
そしたら、ブレークポイントで止まる。

[JavaExec](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.JavaExec.html)
[Gradle to execute Java class (without modifying build.gradle)](https://stackoverflow.com/questions/21358466/gradle-to-execute-java-class-without-modifying-build-gradle)

Stopしたのになんで実行されてんだ感がすごいし、Android Studio 2.xの時より面倒になったけど、~~とりあえず動くので良しとする。~~動かん。


# ~~そしてベストプラクティス~~

前章にあるように、`build.gradle`に`task executeMyClass`を同じように作る。
Add New ConfigurationからRemoteを追加するが、Nameは適当にして、他は全てデフォルトでそのままOKする。

おもむろにshを実行する。

```shell:executeMyClass.sh
./gradlew :lib:executeMyClass --debug-jvm
```
すると、EXECUTINGで止まったままになる。

Android Studioでさっき追加したRemoteをdebugで実行すると...なんとアタッチできる。めでたし。
エラーはターミナルに表示されるので、落ちたクラスにクリックでジャンプはできない。

## Android Studio 2.x時代と同じように実行できる方法を発見したので真のベストプラクティスは**[こちら](https://qiita.com/KoheiKanagu/items/cec6026ea3f3e86a1ce8)**



## 余談
Android Studio 2.xの時と比べるとすごい手間であるが、時代に取り残されないようにするためにはこうするしかないのか...？
そもそもAndroid StudioでJavaアプリケーションを動かすのが間違ってるのかもしれない。（と思ったけど、Androidなモジュールがないプロジェクトであれば、ApplicationのConfigurationから実行は可能なのが余計に謎）
Gradle plugin 3.xでimplementationとかapiとか増えたせいの仕様変更が原因な気がするけど実際問題よく分からん...