技術ネタはQiitaに移りました。壁もどこぞに。

IntelliJ IDEA 15 の Spring Boot 用 起動構成で ClassNotFoundException

IntelliJ IDEA 15 EAP をしばらく前から使用してみている。

IntelliJ IDEA 15 からは、Spring Boot 人気を受けてか、専用の起動構成が用意されている。アクティブ プロファイルの設定や、パラメーターの上書きなどが構成設定内に用意されており、Spring Boot に最適化されているのがよく分かる。

f:id:Yoichi-KIKUCHI:20150925000052p:plain

また、これまで Maven 経由で起動していたような場合には、多重起動が検出できず、二度目以降の起動時には公開ポートの衝突などが度々発生していたが、これも Spring Boot 用の起動構成では解消されており、なかなか便利になっている。

f:id:Yoichi-KIKUCHI:20150924234653p:plain

ところが、これまで Maven コマンドなどで起動していた場合、Spring Boot 用の起動構成に切り換えても、そのままでは動作しない場合がある。以下の様な例外がスローされてしまう。

java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration#propertySourcesPlaceholderConfigurer due to internal class not found. This can happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:51)

...

Caused by: java.lang.NoClassDefFoundError: javax/servlet/Filter
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.getDeclaredMethods(Class.java:1975)

...

起動時に、Servlet API 関連のクラスが見つからない、とのこと。関連キーワードで検索したらすぐに、Stackoverflow がヒットした。

stackoverflow.com

これを修正するには pom.xml を修正する必要がある。組み込み Tomcat などを依存関係に追加している場合、provided スコープになっている設定があれば、これを以下のように除去してやる。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <!--<scope>provided</scope>-->
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <!--<scope>provided</scope>-->
</dependency>

Spring Boot 用の起動構成では、アプリケーションをスタンドアロン起動するため、アプリケーションコンテナなどに依存するような、ライブラリの取得をしてはいけなかったようだ。これで新たに IntelliJ IDEA 15 で追加された、この便利な起動構成を活用できるようになる。