継続的デリバリーのためのJNDI

最近流行りの継続的デリバリー(Continuous Delivery)のプラクティスの1つに

バイナリは一度だけビルドする

というものがあります。

テストがちゃんと通ったバイナリをそのまま本番環境にリリースしましょうね、というプラクティスです。たぶん。 このプラクティスを実践しようとすると、Mavenで環境ごとのプロファイル切り替えてビルドするのはNGということになります。よくあるのがデータベースへの接続情報ですね。今まではこのように書いていました。

<profile>
	<id>development</id>
	<activation>
		<activeByDefault>true</activeByDefault>
	</activation>

	<properties>
		<javax.persistence.jdbc.driver>org.h2.Driver</javax.persistence.jdbc.driver>
		<javax.persistence.jdbc.url>jdbc:h2:mem:development</javax.persistence.jdbc.url>
		<javax.persistence.jdbc.user />
		<javax.persistence.jdbc.password />
	</properties>
</profile>
<profile>
	<id>production</id>
	<properties>
		<!-- productionではテストをスキップする -->
		<maven.test.skip>true</maven.test.skip>

		<javax.persistence.jdbc.driver>com.mysql.jdbc.Driver</javax.persistence.jdbc.driver>
		<javax.persistence.jdbc.url>jdbc:mysql://localhost/production</javax.persistence.jdbc.url>
		<javax.persistence.jdbc.user />
		<javax.persistence.jdbc.password />
	</properties>
</profile>

リリース用プロファイル(production)はmaven.test.skipをtrueにして本番のデータベースでテストを動かさないようにしています。 これらの情報をバイナリの外に出すにはどうしたらよいでしょうか?前置きが長くなりましたが、今回はJavaでお馴染みのJNDIを使って解決する方法をご紹介します。

テスト環境でどうやってJNDI使うの?

さて、GlassfishやTomcatなどのアプリケーションサーバー上であればJNDIを使うのも簡単なのですが、JenkinsなどでテストでJNDIを使うにはどうしたらよいでしょうか。

Spring FrameworkにはApache Geronimoの成果物であるApache XBeanを使うことでJNDIを提供できるのですが、Spring Frameworkを使わないプロジェクトの場合はなかなか難しいかと思います。

そこで、オンメモリで動くシンプルなJNDIコンテナ実装、その名もsimple-jndiを使った方法をご紹介します。

simple-jndi

Mavenのセントラルリポジトリにデプロイされているので、以下のdependencyを追加してください。

<dependency>
	<groupId>simple-jndi</groupId>
	<artifactId>simple-jndi</artifactId>
	<version>0.11.4.1</version>
	<scope>test</scope>
</dependency>

scopeをtestにしておくことで、リリースビルドには含まれないようにします。

次にsrc/test/resourcesにjndi.propertiesを追加し、simple-jndiを使うように設定します。

java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
org.osjava.sj.root=file://src/test/resources

java.naming.factory.initialにはsimple-jndiのjavax.naming.spi.InitialContextFactory実装、org.osjava.sj.rootはsimple-jndiが参照する設定ファイルのルートディレクトリです。サンプルを見たらclasspathスキームを使えるような事が書いてあったのに、実装をみたらfileスキームしか使えなかった・・・!commons-vfsあたりで様々なスキーム使えるようにしてコントリビュートしたいかも。

さて、試しにjavax.sql.DataSourceの設定を記述してみます。

type=javax.sql.DataSource
url=jdbc:h2:mem:development;DB_CLOSE_DELAY=-1
driver=org.h2.Driver
user=
password=

データベースにはh2databaseを使っています。上記のテキストをsrc/test/resources/datasource.propertiesとして保存しましょう。

設定はこれだけです。上記の場合datasourceという名前でjavax.sql.DataSourceがlookupできます。簡単ですね!

https://github.com/nagaseyasuhito/fatsia

にsimple-jndiを使ったテストを書いてあるので、参考にしてみてください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>