CLOVER🍀

That was when it all began.

GradleでWebアプリを作ってみようと…

タイトルの通り、今度はGradleのWar PluginとJetty Pluginを使ってWebアプリ…というかサーブレットプログラミングをやってみようと思ったのですが、うまくいきませんでしたという…。

一応、以下を見ながらやったんですけどね、何がマズかったんでしょう?
http://www.gradle.org/docs/current/userguide/web_project_tutorial.html
http://www.gradle.org/docs/current/userguide/war_plugin.html
http://www.gradle.org/docs/current/userguide/jetty_plugin.html

やったことは書いておきますか。

プロジェクトの作成

まずは、Webアプリ用のプロジェクト…というか、ディレクトリ作成。

$ mkdir hello-gradle-webapp
$ cd hello-gradle-webapp/
$ mkdir -p src/main/groovy src/main/webapp/WEB-INF

Mavenと同様、Web関連のファイルは「src/main/webapp」ディレクトリに置くようです。

ファイルの配置

まずは、build.gradleの作成。

apply plugin: 'groovy'
apply plugin: 'war'
apply plugin: 'jetty'

repositories {
    mavenCentral()
}

dependencies {
    groovy 'org.codehaus.groovy:groovy:2.0.1'
}

次に、web.xmlをGroovletsとGSPを使うように書いて

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         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_2_5.xsd"
         version="2.5">

  <servlet>
    <servlet-name>Groovy</servlet-name>
    <servlet-class>groovy.servlet.GroovyServlet</servlet-class>
  </servlet>

  <servlet>
    <servlet-name>GSP</servlet-name>
    <servlet-class>groovy.modules.pages.GroovyPages</servlet-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>debug</param-name>
      <param-value>0</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>Groovy</servlet-name>
    <url-pattern>*.groovy</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>GSP</servlet-name>
    <url-pattern>*.gsp</url-pattern>
  </servlet-mapping>

</web-app>

簡単なGroovyスクリプトを用意したのですけどね。実行すると

$ gradle jettyRun
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jettyRun
failed org.gradle.api.plugins.jetty.internal.JettyPluginWebAppContext@39150481{/hello-gradle-webapp,/home/ippei/study/groovy/starlight/hello-gradle-webapp/src/main/webapp}: java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet
failed ContextHandlerCollection@3f37484d: java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet
failed HandlerCollection@466bd7a7: java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet
Error starting handlers
java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
	at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:355)

 〜省略〜

	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
	... 131 more
> Building > :jettyRun > Running at http://localhost:8080/hello-gradle-webapp

盛大に、HttpServletクラスが見つからないといってコケてくれますが?

なお、この状態でもJetty自体は起動しています。Servletのロードに失敗しているようなので、まともには動きませんが。

これの意味がまったくわからず、他にもこれでハマっている人がいたようでそれを参考にbuild.gradleのdependenciesに

dependencies {
    groovy 'org.codehaus.groovy:groovy:2.0.1'
    compile 'commons-io:commons-io:1.4'
    compile 'log4j:log4j:1.2.15@jar'
    compile 'javax.servlet:servlet-api:2.5'
}

servlet-apiとcommons-io、log4jを足してみたのですが全然動く気配なし。

いろいろ試してわかったのは、web.xmlを置く…というかサーブレットの定義を書くとアウトだということっぽいです。web.xmlを削除したりすると、普通に起動します。そして、配布されているサンプル用のWebプロジェクトにもweb.xmlはありません…。

これって、どうなってるんでしょうね?

今回は、もういいやーって諦めてしまいました。うん、微妙…。