: EasyBuggy Boot - Spring Tools 4 Eclipseで開発・デバッグする


EasyBuggy Bootとは

メモリリーク、デッドロック、JVMクラッシュ、SQLインジェクションなど、バグや脆弱性の動作を理解するためにつくられたバグだらけのWebアプリケーションです。Apache 2.0ライセンスで公開されています。

開発・デバッグできるようにするまで

作者がEASYBUGGY BOOTのトリセツに情報をまとめている。
しかし、2021年現在の私の環境では、そのまま実行してもうまくいかなかった。
このため、本記事にて改めて開発、デバッグできるようにするまでの手順をまとめる。

本記事では、Spring Tools 4 for Eclipse(Windows 64-BIT)を利用している。

前提

Java(JDK) 8とmavenがインストールされていること。
インストールされていない場合は、下記の記事を参考に。

Spring Tools 4 for Eclipseのダウンロード

下記ページからSpring Tools 4 for Eclipseを選択し、spring-tool-suite-4-4.9.0.RELEASE-e4.18.0-win32.win32.x86_64.self-extracting.jar(2021年3月10日時点)をダウンロードする。

ファイルの解凍(展開)

ダウンロードされたjarファイルを、Spring Tools 4を配置する任意のフォルダに移動させる。
ダブルクリックして実行すると、sts-4.9.0.RELEASEフォルダが作成される。

Spring Tools 4の実行

フォルダ内のSpringToolSuite4.exeを実行する。
すると、スプラッシュスクリーンが表示されるので、しばらく待つ。

ワークスペースディレクトリの選択

特に希望がなければこのままでよい。Launchボタンを押す。

Spring Tools 4メイン画面の確認

特に問題がなければ、このような画面が表示される。
左上に表示されているPackage Explorer内の選択肢から、Import projects... を選択する。

プロジェクトのインポート

Importダイアログ内のGit > Projects from Git(with smart import) を選択する。

Clone URIを選択する。

Location > URIhttps://github.com/k-tamura/easybuggy4sb.gitを入力する。Nextボタンを押す。

Nextボタンを押す。

Nextボタンを押す。

Finishボタンを押す。

Mavenプロジェクトのビルド

自動的にMavenプロジェクトとしてビルドされるので、しばらく待つ。(5分程度)

起動(に失敗する)

Boot Dashboardペイン内のStart or restart the process associated with the selected elements in debug mode ボタンを押す。

・・・と、ClassCastExceptionが発生して終了してしまう。

Exception in thread "main" java.lang.ClassCastException: class jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to class java.net.URLClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader and java.net.URLClassLoader are in module java.base of loader 'bootstrap')
    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)
    at org.springframework.boot.devtools.restart.Restarter.initialize(Restarter.java:546)
    at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationStartingEvent(RestartApplicationListener.java:67)
    at org.springframework.boot.devtools.restart.RestartApplicationListener.onApplicationEvent(RestartApplicationListener.java:45)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:122)
    at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:69)
    at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:48)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:292)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
    at org.t246osslab.easybuggy4sb.Easybuggy4sbApplication.main(Easybuggy4sbApplication.java:15)

DevToolsを削除する

仕方がないので、回避策をとる。
Package Explorer内のeasybuggy4sbプロジェクトを右クリックし、 Spring > Remove DevTools を選択する。

DevToolsを削除した後に、再度起動を試みる。

しかし、今度は別のエラーが発生してしまう。

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2021-03-10 23:56:56.503 ERROR 27856 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'halMessageConverterSupportedMediaTypeCustomizer': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/hateoas/mvc/TypeConstrainedMappingJackson2HttpMessageConverter
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration.createChildManagementContext(EndpointWebMvcAutoConfiguration.java:193) ~[spring-boot-actuator-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration.afterSingletonsInstantiated(EndpointWebMvcAutoConfiguration.java:156) ~[spring-boot-actuator-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:781) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) ~[spring-boot-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.t246osslab.easybuggy4sb.Easybuggy4sbApplication.main(Easybuggy4sbApplication.java:15) ~[classes/:na]
Caused by: java.lang.NoClassDefFoundError: org/springframework/hateoas/mvc/TypeConstrainedMappingJackson2HttpMessageConverter
    at org.springframework.boot.autoconfigure.hateoas.HypermediaHttpMessageConverterConfiguration$HalMessageConverterSupportedMediaTypesCustomizer.configureHttpMessageConverter(HypermediaHttpMessageConverterConfiguration.java:83) ~[spring-boot-autoconfigure-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.autoconfigure.hateoas.HypermediaHttpMessageConverterConfiguration$HalMessageConverterSupportedMediaTypesCustomizer.configureHttpMessageConverters(HypermediaHttpMessageConverterConfiguration.java:77) ~[spring-boot-autoconfigure-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at org.springframework.boot.autoconfigure.hateoas.HypermediaHttpMessageConverterConfiguration$HalMessageConverterSupportedMediaTypesCustomizer.configureHttpMessageConverters(HypermediaHttpMessageConverterConfiguration.java:67) ~[spring-boot-autoconfigure-1.5.7.RELEASE.jar:1.5.7.RELEASE]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    ... 24 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[na:na]
    ... 34 common frames omitted

Spring Bootのバージョンを上げる

pom.xmlを開き、spring-boot-starter-parentのversionを最新に書き換える。

Before
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.6.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>
After
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.22.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

(ようやく)起動成功

Consoleに下記のようなログが出力されたら成功。

2021-03-11 00:07:43.360  INFO 17724 --- [           main] o.t.e.Easybuggy4sbApplication            : Started Easybuggy4sbApplication in 5.688 seconds (JVM running for 6.237)

http://localhost:8080/にアクセスすると、EasyBuggyのメインページが表示される。

おつかれさまでした。

関連記事