Heroku/Cedar上でSAStruts+S2JDBCを動かす その1

元ネタはこちら。

Getting Started with Spring MVC Hibernate on Heroku/Cedar

Heroku上でSpring MVC Hibernateが動くなら、SAStruts+S2JDBCも動くはず。

ということで実験。

事前の環境構築についてはこちらこちらを参照。

 

まずは元ネタから手順を確認。

  1. Create a Java App That Uses Spring MVC and Hibernate
  2. Modify Database Configuration
  3. Add Jetty Runner
  4. Declare Process Types in a Procfile
  5. Run Your App Locally
  6. Deploy to Heroku/Cedar

 SAStruts+S2JDBCの場合はこんな感じ。

  1. Doltengでプロジェクト作成
  2. データベース設定変更
  3. Jetty Runner追加
  4. Procfileの作成
  5. ローカルでの動作確認
  6. Heroku/Cedarへのアップロード

主な違いは

  • Spring RooではなくDoltengを使う
  • データベース設定に環境変数読み取りの仕組みを追加
  • Heroku/Cedarへのアップロードの際にローカルのDBをインポートする

といったところ。詳細は各項目ごとの説明を参照。

 

1.Doltengでプロジェクト作成

このあたりを参考にプロジェクト作成。もちろんSAStruts+S2JDBCにしておく。

今回はDB上にテーブルを作成し、Doltengのscaffoldを利用する。

まずはPostgreSQL上でCREATE TABLEしておく。

今回作ったのは以下のシンプルなテーブル。

CREATE TABLE users
(
  id serial NOT NULL,
  first_name character varying(100),
  last_name character varying(100),
  CONSTRAINT pk_users PRIMARY KEY (id )
)

 このテーブルを元にscaffoldします。

scaffoldについてはこのあたりを参照。

※もちろんjdbc.diconとs2jdbc.diconにURLやユーザー名、パスワードなどの設定が必要。あらかじめ設定しておきましょう。

 

2.データベース設定変更

Heroku上ではDatabase接続情報は環境変数「DATABASE_URL」に格納されている。

フォーマットは以下のとおり。

postgres://user:password@hostname/path

元ネタでは

<bean class="java.net.URI" id="dbUrl">
    <constructor-arg value="${DATABASE_URL}"/>
</bean>

 として環境変数を利用してURIインスタンス(dbUrl)を生成し、

データベース接続設定ファイルにて

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
    <property name="driverClassName" value="${database.driverClassName}"/>
    <property name="url" value="#{ 'jdbc:postgresql://' + @dbUrl.getHost() + @dbUrl.getPath() }"/>
    <property name="username" value="#{ @dbUrl.getUserInfo().split(':')[0] }"/>
    <property name="password" value="#{ @dbUrl.getUserInfo().split(':')[1] }"/>
    ...

という形で利用している。

これをS2JDBC用に置き換えるため、以下のヘルパークラスを作成する。

package com.febc.heroku.util;

import java.net.URI;
import java.net.URISyntaxException;

public class HerokuEnvironmentHelper {

    private static HerokuEnvironmentHelper instance;

	public static HerokuEnvironmentHelper getInstance()
			throws URISyntaxException {
		if (instance == null) {
			instance = new HerokuEnvironmentHelper();
		}
		return instance;
	}

	private URI DB_URI;
	private static final String DB_URI_ENV_NAME = "DATABASE_URL";

	private HerokuEnvironmentHelper() throws URISyntaxException {
		DB_URI = new URI(System.getenv(DB_URI_ENV_NAME));
	}

	public String getUrl() {
		return "jdbc:postgresql://" + DB_URI.getHost() + DB_URI.getPath();
	}

	public String getUsername() {
		return DB_URI.getUserInfo().split(":")[0];
	}

	public String getPassword() {
		return DB_URI.getUserInfo().split(":")[1];
	}

}
    
    

これでdiconファイル中に環境変数からのDB接続情報を設定できる。

jdbc.diconはこんな感じ。

<component name="xaDataSource"
    	class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
	<property name="driverClassName">
		"org.postgresql.Driver"
        </property>
        <property name="URL">
	        @com.febc.heroku.util.HerokuEnvironmentHelper@getInstance().url
        </property>
        <property name="user">
		@com.febc.heroku.util.HerokuEnvironmentHelper@getInstance().username
	</property>
        <property name="password">
		@com.febc.heroku.util.HerokuEnvironmentHelper@getInstance().password
	</property>
</component>

 ローカルで動かす場合にも環境変数「DATABASE_URL」が必要となるので設定しておく。

 

3.Jetty Runner追加

 これは元ネタのままでOK。Doltengでプロジェクトを作成しているためpom.xmlも生成されているはず。plugins配下に以下を追記。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.3</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals><goal>copy</goal></goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>org.mortbay.jetty</groupId>
                        <artifactId>jetty-runner</artifactId>
                        <version>7.4.5.v20110725</version>
                        <destFileName>jetty-runner.jar</destFileName>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

 

ついでに、依存jarについてもここで記載しておく。

dependencies配下に以下を追加。

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
</dependency>
<dependency>
    <groupId>postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>9.1-901.jdbc3</version>
</dependency>

続きは次回へ。