問題
- Spring boot devtools + gradle を Eclipse で 「Spring Boot アプリケーション」として実行すると、
ClassCastException
が発生する - gradleから「bootRun」で実行すると、起動は成功するが、コードの変更が反映されない
解決策
- gradleの「bootRun」で起動する
- プロジェクトの「自動的にビルド」にチェック
- 「Javaのビルド・パス」をgradleのビルド先に合わせる
解説
参考)
[Java] Spring BootでHello World!(入門編) | マリンロード
1. スタータープロジェクトの作成
まずは、SpringBootのスタータープロジェクトを作成します。
- 型: Gradle(Buildship 2.x)
- パッケージング: war
- Javaバージョン: 8
- 言語: Java
後はデフォルトのまま
- Spring Boot Version: 1.5.10
- DevTools
- Thymeleaf
- Web
依存関係として、上記のみを選択します。
- ベースURL:
http://start.spring.io/starter.zip
- 完全URL:
http://start.spring.io/starter.zip?name=demo03&groupId=com.example&artifactId=demo03&version=0.0.1-SNAPSHOT&description=Demo+project+for+Spring+Boot&packageName=com.example.demo&type=gradle-project&packaging=war&javaVersion=1.8&language=java&bootVersion=1.5.10.RELEASE&dependencies=devtools&dependencies=thymeleaf&dependencies=web
2. HelloController.javaの作成
スタータープロジェクトが出来たら、HelloController
を追加します。
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "Hello World !!";
}
}
3. 「Spring Boot アプリケーション」として実行
プロジェクトを右クリックして出てくる「Spring Boot アプリケーション」を実行します。
Exception in thread "main" java.lang.ClassCastException: java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to java.base/java.net.URLClassLoader
at org.springframework.boot.devtools.restart.DefaultRestartInitializer.getUrls(DefaultRestartInitializer.java:93)
at org.springframework.boot.devtools.restart.DefaultRestartInitializer.getInitialUrls(DefaultRestartInitializer.java:56)
at org.springframework.boot.devtools.restart.Restarter.<init>(Restarter.java:140)
(略)
щ(゚ロ゚щ) オーマイガーッ!!
…ってのが、今回の発端です。Java9で ClassCastException
が起きるってのは調べたらよく出てきたのですが、今回はJava8だし…
で、次に試したのが、そもそもgradleプロジェクトなんだから、gradleから起動したらいけんじゃね?って事。
4. gradleの「bootRun」で実行する
(*^-゚)vィェィ♪
うまくいきましたー!…って思ったのもつかの間。
ソースコードを修正しても即反映されない…… orz
もちろんgradleタスクを止めて、再度実行すれば反映されますが、せっかく DevTools
を使ってるんだから、即時反映させたい!
そして試行錯誤することしばし……
5. プロジェクトのビルドパスを変更する
試行錯誤の結果、ソースコードを保存した時の自動ビルドパスが、gradleのビルドパスと合ってない事に気づきました。
Eclipseのビルドパスの設定を何も変えていないと、 bin
ディレクトリ以下にビルド結果が保存されるようです。
これを gradle のビルドに合わせて変えてみたら……?
src/main/java
… 出力フォルダ: build/classes/main
src/main/resources
… 出力フォルダ: build/resources
src/test/java
… 出力フォルダ: build/classes/test
☆(^o^)乂(^-^)☆ ヤッタネ!!
ソースコードを保存したら、即時反映されるようになりました!
※resourcesの下は確認してないので、パスが間違ってたらすみません。