-
Notifications
You must be signed in to change notification settings - Fork 9
Java
このクイックスタートはHerokuにデプロイされるJavaとJettyが組み込まれたWebサーバについて扱って行きます。Herokuを使ったアプリケーションの開発と設計の仕方についての一般的な情報は、Architecting Applications for Herokuを確認してください。
{.note} JavaのデモアプリケーションのためのサンプルコードはGitHubで利用可能です。編集や改善は歓迎します。
- 基本的なJavaの知識。JVMのインストールされているバージョンそしてMaven 3を含みます。
- あなたのアプリケーションはOpenJDK version 6, か 7 (8もベータが利用可能)の上で走っていること
- Herokuのユーザアカウント。こちらで無料で簡単に取得ができます。
もしあなたがEclipseのユーザなら、これらのステップを飛ばしてEclipseの開発環境を使って始める事が出来ます。Getting Started with Heroku & Eclipseを見てみてください。
Heroku Toolbeltをローカルにインストール します。これはあなたのHeroku command-line client、Foreman、そしてGitのバージョン管理システムへアクセスを確かなものにします。
一度インストールできると、heroku
コマンドがシェルから使えるようになります。アカウントを作ったときに使ったE-mailアドレスやパスワードを使ってログインしてみます :
:::term
$ heroku login
Enter your Heroku credentials.
Email: adam@example.com
Password:
Could not find an existing public key.
Would you like to generate one? [Yn]
Generating new SSH public key.
Uploading ssh public key /Users/adam/.ssh/id_rsa.pub
エンターキーをおすとすぐに存在しているssh
キーか新しいものをアップロードしてくれます。後でコードをプッシュするときに使います。
どんなJavaのアプリケーションでもビルドツールであるMavenを使って、Herokuで実行できるようになりました。例として、Jettyを使ったWebアプリケーションを書いてみます。ここにアプリを開始するための基本的なメソッドが含まれている基本的なサーブレットクラスがあります。
:::java
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.*;
public class HelloWorld extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.getWriter().print("Hello from Java!\n");
}
public static void main(String[] args) throws Exception{
Server server = new Server(Integer.valueOf(System.getenv("PORT")));
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
context.addServlet(new ServletHolder(new HelloWorld()),"/*");
server.start();
server.join();
}
}
HerokuはJavaのアプリをpom.xml
ファイルの存在によって認識します。ここに上で作ったJava/Jettyアプリのためのpom.xml
の例を載せます。
:::xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>helloworld</artifactId>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>7.6.0.v20120127</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals><goal>copy-dependencies</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
バージョン管理内に余計なものが含まれてしまわないように、このファイルを作ります :
:::term
target
ローカルでアプリケーションを作成します :
:::term
$ mvn package
ビルドの一部分として、Mavenは依存性のあるファイルを集めて、target/dependency
の中にコピーします。PORT環境変数を設定し、依存性のあるファイルへのパスを指定しながらJavaを実行してアプリケーションを開始します:
Mac もしくは Linux:
:::term
$ export PORT=5000
$ java -cp target/classes:"target/dependency/*" HelloWorld
(ダブルクォート"
は*
が展開されるのを防ぐために必要です。)
Windows:
:::term
$ set PORT=5000
$ java -cp target\classes;"target\dependency\*" HelloWorld
すると以下のような物が見えてきます :
:::term
2012-01-31 15:51:21.811:INFO:oejs.Server:jetty-7.6.0.v20120127
2012-01-31 15:51:21.931:INFO:oejsh.ContextHandler:started o.e.j.s.ServletContextHandler{/,null}
2012-01-31 15:51:21.971:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:5000
ブラウザでアプリを開きます : http://localhost:5000
アプリケーションのルートディレクトリの中のテキストファイルであるProcfileを使って、Webdynoを開始するために何のコマンドが実行されるべきかを明示的に宣言します。
Procfile
はこのような見た目になります。
:::term
web: java -cp target/classes:target/dependency/* HelloWorld
(注意: Procfile内ではダブルクォートはいりません。)
デフォルトではOpenJDK1.6がインストールされています。ですが、新しいJDKを使う事もできます。使う場合はsystem.properties
ファイルの中にjava.runtime.version=1.7
と指定します。
system.properties
はこのような見た目をしています :
:::term
java.runtime.version=1.7
Java 6, 7, 8(ラムダ式が使えます) のそれぞれで、1.6, 1.7, 1.8(1.8はベータです)を指定することができます。
今、私たちはアプリの中に3つの主要な構成要素を持っています。pom.xml
の中のビルド設定と依存関係ファイル、Procfile
の中のプロセスタイプ、そしてsrc/main/java/HelloWorld.java
の中にある私たちのアプリのソースです。Gitに追加していきましょう :
:::term
$ git init
$ git add .
$ git commit -m "init"
(Herokuの)アプリケーションを作成します :
:::term
$ heroku create
Creating stark-sword-398... done, stack is cedar
http://stark-sword-398.herokuapp.com/ | git@heroku.com:stark-sword-398.git
Git remote heroku added
コードをデプロイします :
:::term
$ git push heroku master
Counting objects: 47, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (25/25), done.
Writing objects: 100% (47/47), 10.25 KiB, done.
Total 47 (delta 19), reused 42 (delta 17)
-----> Heroku receiving push
-----> Java app detected
-----> Installing OpenJDK 1.6... done
-----> Installing Maven 3.0.3... done
-----> Installing settings.xml... done
-----> executing /app/tmp/repo.git/.cache/.maven/bin/mvn -B -Duser.home=/tmp/build_3k0p14ghrmdzs -Dmaven.repo.local=/app/tmp/repo.git/.cache/.m2/repository -s /app/tmp/repo.git/.cache/.m2/settings.xml -DskipTests=true clean install
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building helloworld 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.062s
[INFO] Finished at: Tue Jan 31 23:27:20 UTC 2012
[INFO] Final Memory: 12M/490M
[INFO] ------------------------------------------------------------------------
-----> Discovering process types
Procfile declares types -> web
-----> Compiled slug size is 948K
-----> Launching... done, v3
http://empty-fire-6534.herokuapp.com deployed to Heroku
Herokuにコードをデプロイしました、そしてProcfile
の中にプロセスタイプを指定しました。今、あなたはHerokuに対してプロセスタイプを実行するための指示を出す事が出来ます。Herokuは
dynoに関連づいたコマンドを実行することでこれを行います。dynoとはHerokuにおける基本的な構成要素の単位になっている軽量コンテナのことです。
web
プロセスタイプが実行されているdynoがあることを確かめてみましょう :
:::term
$ heroku ps:scale web=1
アプリケーションのdynoの状態を確認することができます。このheroku ps
コマンドはあなたのアプリケーションの実行中のdynoをリストします :
:::term
$ heroku ps
=== web: `java -cp target/classes:target/dep...`
web.1: up for 5s
ここにdynoが一つ走っています。
heroku open
を使ってブラウザでアプリを確認することができます。
:::term
$ heroku open
Opening empty-fire-6534... done
実行中のWeb dynoを一つだけ持っている事は、dynoが非アクティブになったあと1時間経つとスリープすることを意味します。これは再度立ち上がるときの最初のリクエストに対して数秒の遅れが発生することを意味します。後続のリクエストは通常通りに帰ってくるでしょう。
これを避けるために、web dynoを1個以上に増やすことが出来ます。例えば :
:::term
$ heroku ps:scale web=2
それぞれのアプリケーションごとに、Herokuは750時間のdyno無料利用時間を提供しています。2個のdynoで動いているアプリケーションは、月々のこの無料利用時間を超える可能性が高いので、増やしたものを戻してみましょう :
:::term
$ heroku ps:scale web=1
Herokuは、アプリケーションの内容物を実行しているすべてのdynoの出力ストリームから時系列イベントのストリームとしてログを扱います。HerokuのLogplexはこれらのイベントの全てをあつかう単体のチャネルを提供しています。
ログ用コマンドの一つを使って、実行中のあなたのアプリケーションの情報を見てみましょう。heroku logs
を実行します。 :
:::term
$ heroku logs
2012-01-31T23:27:27+00:00 heroku[web.1]: Starting process with command `java -cp target/classes:target/dependency/* HelloWorld`
2012-01-31T23:27:28+00:00 app[web.1]: 2012-01-31 23:27:28.280:INFO:oejs.Server:jetty-7.6.0.v20120127
2012-01-31T23:27:28+00:00 app[web.1]: 2012-01-31 23:27:28.334:INFO:oejsh.ContextHandler:started o.e.j.s.ServletContextHandler{/,null}
2012-01-31T23:27:28+00:00 app[web.1]: 2012-01-31 23:27:28.373:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8236
2012-01-31T23:27:29+00:00 heroku[web.1]: State changed from starting to up
- Spring MVC Hibernate チュートリアルはHerokuのデータベース駆動のアプリケーションを構築するためのガイドになるでしょう。
- 開発についてとJavaのアプリケーション開発についてより学びたい場合はJavaカテゴリを訪れてみてください。
- アプリケーションを書いたり、構成したり、デプロイしたり、実行する時に直面するだろう概念について、技術的な大枠を知りたい場合はHerokuの仕組みを読むといいでしょう。