dotCloudにJava HttpServletなものをデプロイしてみる
どもー(´ω`)ノ Ramencozoです
最近dotCloudさんとこにアプリをポイポイ投げてるます(´ω`)
でもってdotCloudに素のJava Servlet(Jettyのソレ)を投げる方法を探してましたが、ネット上にズバリコレ的なのが見つかんなくてでして(´ω`)みなさんPython(Django)だとかJava Framework(Play!)だとかでの話がほとんどでウッヒャーすごいスなーと思いつつ、「もっと素での実装ないの」と思いつつ。
どうにかこうにかヤッてみたらイケました(´ω`)ふぃー
下記環境で試行錯誤。
・JDK 1.6 (dotCloudの環境がソレなので)
・eclipse indigo (なんでもいいです)
・Jetty8 (dotCloudのはJetty6ですが、ダウソ先が見つからず)
-> servlet-api-3.0.jar
とりあえずHelloWorld的なナニを書くこととします。
まずはJava Projectのフォルダ構成。
src以下は.javaなソースを置くところ、dotcloudフォルダは実際にdotCloudにデプロイするwarファイル(クラスファイルとかをまとめたもの)等を置くところ、libフォルダはプロジェクト内で使用するjarファイルを置くところ、WEB-INFフォルダはwarファイルの中身に当たるフォルダで、この中にclassesフォルダ(.classファイルを置くところ、画像では見えてませんが実際は存在してます)、libフォルダ(上位のlibフォルダと同じもの)、web.xml(Servletの各種設定)を配置します。
作業しやすいように、通常binフォルダに吐かれるclassファイルをWEB-INFのclassesフォルダに吐くように設定します。Build Path → Configure Build Path → Sourceタブ → 下部の Default output folder のところをBrowseして指定します。
でもってHelloWorld的なHttpServletを書きます。HelloWorldだけじゃさびしいんで現在時刻も表示するようにしてます。
Hello.java / HelloDotCloud
import java.io.IOException; import java.io.PrintWriter; import java.util.Calendar; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Hello extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Calendar calendar = Calendar.getInstance(); int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); int second = calendar.get(Calendar.SECOND); resp.setContentType("text/html; charset=UTF-8"); PrintWriter writer = resp.getWriter(); writer.print("<html>"); writer.print("<head>"); writer.print("<title>Hello, dotCloud !</title>"); writer.print("</head>"); writer.print("<body>"); writer.print("<p>Hello, dotCloud !</p>"); writer.print("<p>" + hour + ":" + minute + ":" + second + "</p>"); writer.print("</body>"); writer.print("</html>"); writer.flush(); writer.close(); } }
次にweb.xmlを編集します。「http://サーバURL/」にアクセスするとServletが起動するようにします。servlet-nameはXML内での変数名みたいなものでなんでもいいです。servlet-classは実際に動かすHttpServletクラスのクラス名(ここではHello)です。url-patternはサーバドメインの後に続くURLをどうするか決める項です。ここでは"/"なのでサーバURLにペッてアクセスするとそのまま起動します。"/hello"とかにすると"http://サーバURL/hello"とかでアクセスできるようになります。
web.xml / HelloDotCloud
<?xml version="1.0" ?> <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/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>HelloDotCloud</display-name> <servlet> <servlet-name>hello</servlet-name> <servlet-class>Hello</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
ここまで書いたらeclipseですと自動ビルドONならもうclassファイル等整ってるハズなのでwarファイルを作ります。(ビルドされてない場合は手動で)
warファイルはWEB-INFフォルダをzipで圧縮して拡張子をwarに変えただけです。僕は7zipマネージャでzip化した後リネームしました。
ここで、「ROOT.war」という名前にするようにしてください。詳細は後ほど。
次にdotCloudにアプリをデプロイする際の設定ファイルdotcloud.ymlを作成します。文字コードはUTF-8にしてください。(Shift-JISだと認識してくれず動きませんでした…改行コードはたぶんCR+LFでもLFでもOKだと思いますが、一応LFにしといてください)
dotcloud.yml / HelloDotCloud
www: type: java
dotcloud.ymlとROOT.warをdotcloudフォルダに置いてください。
ここでROOT.warと名前を付ける理由ですが、dotCloud上でアプリを動かす際のアクセスURLが「http://アプリ名-ユーザ名.dotcloud.com/WARファイルの名前」という指定になります。これをROOT.warと指定すると「http://アプリ名-ユーザ名.dotcloud.com/」だけで済むようになります。
例えばアプリ名が「hellodotcloud」、ユーザ名が「ramencozo」、warファイル名が「hello.war」だった場合、「http://hellodotcloud-ramencozo.dotcloud.com/hello」にアクセスすることになります。
ここまで整ったらデプロイです。dotCloudの環境構築についてはすいませんググってください。(dotCloud本家にも説明ありますし、他ブログ等でも記事たくさんありますので)
コマンドラインの端末(Windowsだとたぶんcygwinになると思います。Mac、Linuxは標準のターミナルで)にてプロジェクトフォルダ内のdotcloudフォルダまで移動して、下記コマンドを入力してください。
dotcloud create hellodotcloud dotcloud push hellodotcloud .
最初のコマンドでdotCloud上にhellodotcloudという名前のアプリのSandboxが生成され、続くコマンドでROOT.warファイルとdotcloud.ymlのデプロイとアプリ動作環境の構築がdotCloud上で行われます。
コマンドライン出力で最後にURLが示されますのでコピペしてブラウザにてアクセス。
Hello, dotCloud!(ただし時間はdotCloudのサーバのある現地時間っぽいですね…時差9時間くらいあるので、日本時間に直す際はそこ含めた実装がよさそうです)
※ dotCloudはFree Planだと最大2サービスしか利用できないので、そのうちhellodotcloudは消すことになると思います(´ω`)他の試したいときにソレなので