概要
以前紹介したバグだらけのWebアプリケーション「EasyBuggy」のSpring Bootベースのクローン「EasyBuggy Boot」を、Kotlinで再実装してみました(「EasyBuggy Bootlin」)。
このページからダウンロードして、以下のコマンドで起動できます。
起動するにはJava 8以上が必要です。`java -jar ROOT.war --port=9000`とすると9000番ポートで起動します。 |
次のようにJavaオプションを付加すれば、ログ出力やデバッグ、JMXによる監視ができます。また、最大メモリ使用量を制限しているので、OutOfMemoryErrorなどの問題がより発生しやすくなります。
java -Xmx256m -XX:MaxPermSize=64m -XX:MaxDirectMemorySize=90m -XX:+UseSerialGC -Xloggc:logs/gc.log -XX:+PrintHeapAtGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=10M -XX:GCTimeLimit=15 -XX:GCHeapFreeLimit=50 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/ -XX:ErrorFile=logs/hs_err_pid%p.log -agentlib:jdwp=transport=dt_socket,server=y,address=9009,suspend=n -Dderby.stream.error.file=logs/derby.log -Dderby.infolog.append=true -Dderby.language.logStatementText=true -Dderby.locks.deadlockTrace=true -Dderby.locks.monitor=true -Dderby.storage.rowLocking=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=7900 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -ea -jar ROOT.war
以下のようなメッセージが表示されたら、Webアプリケーションの起動は完了しています。
2017-10-19 16:36:01.065 INFO 5304 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8081 (http)
2017-10-19 16:36:01.075 INFO 5304 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2017-10-19 16:36:01.242 INFO 5304 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-10-19 16:36:01.249 INFO 5304 --- [ main] o.t.e.Easybuggy4ktApplicationKt : Started Easybuggy4ktApplicationKt in 37.355 seconds (JVM running for 38.916)
http://localhost:8080 にアクセスすると、メインページが表示されます。

起動がちょっと遅いです(15秒ほど。EasyBuggyは3秒で起動するんですが...)
上記以外の起動方法
git clone
して、gradle bootRun
しても起動できます。
$ git clone https://github.com/k-tamura/easybuggy4kt
$ cd easybuggy4kt
$ gradle bootRun
`src/main/resources/application.properties`の`server.port=${port:8080}`の行を`server.port=9000`にとすると9000番ポートで起動します。 |
また、Tomcat 8.5などのJavaコンテナにROOT.warをデプロイしても同様に動作します。
このアプリの用途
「EasyBuggy」や「EasyBuggy Boot」と同様に、様々な障害を再現させて、解析し、理解を深めることが目的です。なぜKotlinで再実装したかというと、次のことを知りたかったからです。
- Kotlinで実装されたアプリにも脆弱性やリソースリークをつくり込むことはできるか
- Javaで実装されたアプリをKotlinで再実装する上で必要な作業は何か
- Javaで実装されたアプリをKotlinで再実装することで可読性は向上するか
デモ
以下はメモリリークが発生するページに何度もアクセスして、メモリがリークしている状態を観測したデモです。

構成の相違点
「EasyBuggy」、「EasyBuggy Boot」、「EasyBuggy Bootlin」の主な構成の相違点は以下の通りです。
相違点 |
EasyBuggy |
EasyBuggy Boot |
EasyBuggy Bootlin |
言語 |
Java |
Java |
Kotlin |
ベースとなる技術 |
Servlet 3.0.1 |
Spring Boot 1.5.6 (Servlet 3.0.1) |
Spring Boot 1.5.7 (Servlet 3.0.1) |
プレゼンテーション層 |
未使用 (一部 JSP 2.2 + JSTL 1.2) |
Thymeleaf 2.1.5 (一部 JSP 2.3 + JSTL 1.2) |
Thymeleaf 2.1.5 (一部 JSP 2.3 + JSTL 1.2) |
サーブレットコンテナ |
Tomcat 7.0.37 |
Tomcat 8.5.16 |
Tomcat 8.5.20 |
DBクライアント/サーバー |
JDBC / Derby 10.8.3.0 |
Spring JDBC 4.3.9 / Derby 10.12.1.1 (Java 7の場合)、または10.13.1.1 (Java 8の場合) |
Spring JDBC 4.3.11 / Derby 10.13.1.1 |
LDAPクライアント/サーバー |
Apache DS Client API 1.0.0 / Server 1.5.5 |
Spring LDAP 2.3.1 / unboundid-ldapsdk 3.2.1 |
Spring LDAP 2.3.1 / unboundid-ldapsdk 3.2.1 |
メール |
JavaMail 1.5.1 |
JavaMail 1.5.1 (Spring Boot Mailで導入されるJavaMail 1.5.6をオーバーライド) |
JavaMail 1.5.1 (Spring Boot Mailで導入されるJavaMail 1.5.6をオーバーライド) |
開発ツール |
無し |
Spring Boot Developer Tools 1.5.6 |
Spring Boot Developer Tools 1.5.7 |
ビルドツール |
Maven |
Maven |
Gradle |
Java |
Java 6以上をサポート |
Java 7以上をサポート |
Java 8以上をサポート |
ビルドの方法
以下のコマンドで、実行可能かつデプロイ可能なwarファイルを作成することができます。
開発の方法
EasyBuggy Bootlinの開発には、Kotlinを開発したJetBrains社のIntelliJ IDEAを使用しています。JavaのプログラムをKotlinのプログラムに変換するような役立つ機能があったので、STSではなくIntelliJを選択しました。IntelliJのおかげで、かなり短時間にこのアプリが開発できました。
開発を高速にするためには、gradle build --continuous
で継続的にビルドしながら、gradle bootRun
でEasyBuggy Bootlinを起動するといいです。この方法であれば、ソースコードを修正すると、Spring Boot DevToolsにより自動的にリロードされて、修正が反映されます。
