mike-neckのブログ

Java or Groovy or Swift or Golang

WildFlyでh2データベースを使う

本文が長いので、結論に急ぎたい人はこちら


経緯

JSFがよくわからんので、適当なサンプルを書いてglassfishで実行しようとしたら、

$ bin/asadmin start-domain sample
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
JVM failed to start: com.sun.enterprise.admin.launcher.GFLauncherException: The server exited prematurely with exit code 1.
Before it died, it produced the following output:


Command start-domain failed.

とエラーが出て起動できなくなってた(´・ω・`)

JIRAに登録されているので、今後アップデートされるでしょう…多分

[GLASSFISH-21343] Glassfish fails to start on OSX 10.10.3 - Java.net JIRA

なお、僕の環境は

glassfish4.0だと発生していないらしいので、glassfish4.1をピンポイントでついてくるバグっぽい。そういえば、最近小さいOSのアップデートがあったような記憶…


本題

しかたないので、WildFly8.2.0Finalを使うことにしました。

standaloneバージョンのWildFlyにはh2が標準で付属されてて、かつデータベースドライバーとして登録されているので、それをそのまま利用して接続テストしたら、失敗しました。

打ったコマンド

data-source test-connection-in-pool --name=javaee-sample

返ってきたメッセージ

{
    "outcome" => "failed",
    "failure-description" => "JBAS010440: failed to invoke operation: JBAS010447: Connection is not valid",
    "rolled-back" => true
}

スタックトレースを見るとこんな感じ。

18:01:41,016 WARN  [org.jboss.jca.core.connectionmanager.pool.strategy.OnePool] (management-handler-thread - 36) IJ000604: Throwable while attempting to get a new connection: null: javax.resource.ResourceException: Could not create connection
…省略…
Caused by: org.h2.jdbc.JdbcSQLException: 接続が壊れています: "unexpected status 16777216"
Connection is broken: "unexpected status 16777216" [90067-173]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:331)
…以下略…

で、ググった結果がこちら

[ISPN-4815] Broken connection in server JDBC tests - JBoss Issue Tracker

曰く、h2のバージョンが違うようだねとのこと。調べてみると

$ cd modules/system/layers/base/com/h2database/h2/main/
$ ls
h2-1.3.173.jar  module.xml

WildFlyにのっているh2のバージョンが1.3.173であることがわかった。一方、僕が起動しているh2のバージョンは1.4.186なので、落ちるのもあたりまえだなという感じ。

というわけで、僕が起動しているのと同じバージョンのh2のドライバーをWildFlyに登録することにした。データベースドライバーとデータソースの登録の仕方は下のエントリーが詳しい。

www.mastertheboss.com

mythosil.hatenablog.com

手順

モジュールを追加(以下のコマンドは見やすくするために改行してるけど、実際は改行してない)

module add --name=org.h2
    --resources=path/to/h2/h2-1.4.186.jar
    --dependencies=javax.api,javax.transaction.api

ドライバーを登録

/subsystem=datasources/jdbc-driver=h2database:add(
    driver-name=h2database,
    driver-module-name=org.h2,
    driver-class-name=org.h2.Driver,
    driver-major-version=1,
    driver-minor-version=4)

さっき作ったデータソースを削除

/subsystem=datasources/data-source=javaee-sample:remove()

改めてデータソースを登録

data-source add --name=javaee-sample
    --driver-name=h2database
    --jndi-name=java:/javaee-sample-13
    --connection-url=jdbc:h2:tcp://localhost:9092/~/javaee-sample
    --user-name=user --password=pass

で、改めてテストすると、まだ同じ症状が出てくるので、サンプルのデータソースと同梱されてるh2ドライバーを削除する

サンプルのデータソース削除

/subsystem=datasources/data-source=ExampleDS:remove()

同梱ドライバー削除

/subsystem=datasources/jdbc-driver=h2:remove

これでいけるだろうと思ったら、まだ接続テストが落ちるので、再起動

[standalone@localhost:9990 /] data-source test-connection-in-pool --name=javaee-sample-13
true

通った。


要約

WildFlyでh2を使いたい場合は、次の手順でデータソースを登録する

  1. デフォルトのデータソースを削除
  2. 同梱されてるh2ドライバーを削除
  3. WildFlyを再起動
  4. 使いたいバージョンのh2のjarをモジュール追加
  5. 上記のモジュールをドライバーに登録
  6. データソースを登録

結論

やれやれだった乁( ˙ω˙ )厂

なお、ぶっちゃけxmlをいい感じに書けばいいだけなので、それでやってしまえばよかった感ある…