環境
やったこと
JBoss Tools 4.1のインストール
Help -> Eclipse Marketplaceで「jboss tools」で検索する。
JBoss Tools (Kepler)をインストールする。
JBoss ASサーバをEclipseから起動する設定
Servers -> New で、まぁこんな感じでテキトーに。
プロジェクトはなんもAddしなくてもいいんで、JBossが立ち上がれば一先ずOK
プロジェクトの作成
EJB3.1動かすためのMavenとか、Arquillianの設定ファイルとか、イチから作るのは何気にしんどい(てか知識ゼロでやるのは絶望的にめんどい) ので、JBoss CentralからJavaEE Web Projectで雛形をさくっと作ってもらう。
下記スクショはCreate a blank projectにチェックを入れている。デフォルトのままにしておけば、JSFやらEJBやらJPAやらのサンプルコードも含まれる。今回はソースコードはカラの状態のプロジェクト作りたいんで、コレにチェック入れている。
なお、Target Runtimeは未選択にしておく。
プロジェクト名とかパッケージ名とかはとりあえずデフォを使う。
Maven関連。ここもそのまま。
Finishするとプロジェクトの作成と依存性解決などなどが始まり、やや時間がかかる。終了すれば準備OK。
EJB 3.1のコード書く
package org.jboss.tools.examples.ejb; import javax.ejb.Stateless; @Stateless public class HogeEJB { public int add(int a, int b) { return a + b; } }
これだけかよって感じですが、サンプルなんでとりあえずコーディングはこれでおわり。
EJB 3.1のユニットテスト
でもEJBとか動かすのチョーめんどうなんでしょう? って俺もついさっきまで思ってたわけですが。とりあえずは、論よりコードってことで、おもむろにJUnitを書く。
package org.jboss.tools.examples.ejb; import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; import javax.inject.Inject; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class HogeEJBTest { @Deployment public static Archive<?> createTestArchive() { return ShrinkWrap.create(WebArchive.class, "test.war") .addClasses(HogeEJB.class) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); } @Inject HogeEJB hogeEJB; @Test public void testHogeEJBAdd() { assertThat(3, is(hogeEJB.add(1, 2))); } }
これを実行するまえに、Serversからjbossを立ち上げておく。デプロイはしない。
というわけで、EJBもユニットテストでカンタンに動せるようになってました(驚愕) このサンプルみたいにEJBがナンもしないとイマイチ恩恵感じないだろうけど、実際にはJPAやらなんやらゴチャゴチャと絡むのがJ2EEなわけで。そこを、JUnitでカンタンに動かせるようになっちゃってるのは本当にすごいっす。
ぐぐって色々調べてるとすでにCIで走らせるところもあるみたい。適当なサーバにJBoss入れて(Glassfishでもいいっぽいけど)そこでArquillianを走らせる、という感じ。
ハマりどころなど
- ArchiveExportException
org.jboss.shrinkwrap.impl.base.exporter.zip.JdkZipExporterDelegate$1 call WARNING: Exception encountered during export of archive org.jboss.shrinkwrap.api.exporter.ArchiveExportException: Failed to write asset to output: /WEB-INF/lib/arquillian-testenricher-ejb.jar
Arquillianのドキュメントろくすっぽ読まずにやってたために無駄にハマッた。ざっくりいえば、Arquillianはwar or ear作ってすでに動いてるAPサーバにデプロイしてJUnit走らせる、を自動的にやってくれる。んで、サーバが動いていなければ当然デプロイに失敗する。というか、warを作ったもののそれをコピペしにいく場所が見つからない―だからArchiveExportExceptionなのだけど―ので、当然失敗する。
- NullPointerException
java.lang.NullPointerException at org.jboss.tools.examples.ejb.HogeEJBTest.testHogeEJBAdd(HogeEJBTest.java:30) (以下省略)
上記のテストコードでいうと、HogeEJB hogeEJBへのインジェクションが失敗する。これは、下記のようにbeans.xmlが無くてCDIの設定が効いてないために起こる。詳しくはCDIでぐぐる。
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
- Could not create new instance
java.lang.RuntimeException: Could not create new instance of class org.jboss.arquillian.test.impl.EventTestRunnerAdaptor
プロジェクト -> Maven -> Select Maven Profiles.. をチェックする。下記スクショのように、
- arq-jbossas-remoteにはチェックが有る
- arq-jbossas-managedにはチェックが無い
が正しい。両方にチェックが入っていると、上記の例外が発生する。よくわかってなくて申し訳ないが、名称的にもどっちかだけ使うもんなんでしょうね。
さいごに
Arquillianは、jar吐いてソレ実行とかのテストも出来るようで実際スゴイ。