Jetty の起動速度を改善する

Jetty の起動が遅い!

Jetty は起動の速さが売りのひとつですが、構成によっては起動時に次のメッセージをログ出力してしばらく固まります。数秒から十数秒、ググったら 45 秒なんて例もありました。

No Transaction manager found - if your webapp requires one, please configure one

このとき Jetty は Servlet 3.0 のアノテーションのついたクラスを探したり ServletContainerInitializer の処理をしていて、WEB-INF/lib 以下の jar ファイル数、クラス数が多ければそれだけ時間がかかります。

解決方法

次の設定で解決します。

  • web.xml の metadata-complete
  • jetty の webInfIncludeJarPattern

特に後者の効果が大きいです。(前者は違いを体感できませんでしたが、一部の処理がスキップされるので少しは違いがあるはず)

web.xml の metadata-complete

構成によっては指定できないこともありますが、できるなら true にしてしまいましょう。

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0"
         metadata-complete="true">
</web-app>

jetty の webInfIncludeJarPattern

jetty-maven-plugin を使っている場合は pom.xml に webInfIncludeJarPattern を指定して必要最小限の jar だけ探索させます。 値は ServletContainerInitializer と @HandlesTypes で指定されたクラスを含んだ jar にマッチする正規表現です。ServletContainerInitializer を使わないのであればマッチしないような値を指定します。(空文字は全てにマッチします)

<webInfIncludeJarPattern>^WILL_NOT_MATCH$</webInfIncludeJarPattern>

たとえば Spring は web.xml なしで Spring コンテキストを設定するために SpringServletContainerInitializer を提供しています。この機能を使いつつ Jetty の起動を遅くしないためには webInfIncludeJarPattern を次のように指定します。

<webInfIncludeJarPattern>^spring-web.*\.jar$</webInfIncludeJarPattern>
jetty-maven-plugin の設定例
<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <version>8.1.9.v20130131</version>
  <configuration>
    <webApp>
      <webInfIncludeJarPattern>^spring-web.*\.jar$</webInfIncludeJarPattern>
    </webApp>
    <stopKey>stop</stopKey>
    <stopPort>8091</stopPort>
    <connectors>
      <connector implementation="org.eclipse.jetty.server.bio.SocketConnector">
        <port>8080</port>
      </connector>
    </connectors>
  </configuration>
</plugin>

環境

jetty-maven-plugin: 8.1.9.v20130131