nekop's blog

OpenShift / JBoss / WildFly / Infinispanの中の人 http://twitter.com/nekop

JBossプロジェクトのGitリポジトリの管理

JBoss / WildFly (全部俺) Advent Calendar 2013の6日目です。Hibernateのサイトが新しくなりました。全テヲ保存セヨ。

今日もコントリビュータ向け小ネタでいきましょう。僕のGitのremote設定がどうなっているのかという話。

JBossプロジェクトの開発ツリーはほとんどGitHub上にホストされており、Gitで管理されています。特定プロジェクトのソースを見たり履歴を調べるだけならgithub.comからcloneしておしまいなのですが、修正するためにforkしたり製品側の社内のリポジトリも触ったりということになってそれぞれcloneしてしまってどれがどれだろうってなってしまうのはGitビギナーに起こりがちだと思います。そもそも複数cloneする必要ありませんし、remoteで分けてしまうとremote間の差分とか取れなくなります。

まずcloneするリポジトリは必ずgithub.comの読み取り専用のURLにして、originはこちらを指すようにします。Gitのset-upstreamはoriginを指したままにすることで、引数なしのgit pullで最新を見れる、引数なしのgit pushは権限なしで必ず失敗するようにします。

Infinispanを例にします。

git clone https://github.com/infinispan/infinispan/

修正などでforkした場合はgit remoteで追加します。sshのURLです。

git remote add nekop git@github.com:nekop/infinispan.git

修正ブランチは自分のリポジトリにpushしてpull reqします。ブランチ名はJIRAのIDとどのブランチ向けなのかを含めてispnXXXX-masterという感じ(master向けは省略する、というポリシーでもいいと思います)。

git checkout -b <branch> master
# なおしてcommit
git push nekop <branch>

他にgithub.comのプライベートリポジトリや、Red Hat社内のインターナルGitリポジトリなども同様にremote addしておきます。他人のリポジトリ上の未マージのpull reqに含まれる修正をテストしたり、さらに修正を重ねてpull reqしなおすときも同じでremote addして修正ブランチをチェックアウトするという流れです。

JBoss EAP 6.2.0リリース

JBoss / WildFly (全部俺) Advent Calendar 2013の5日目です。クリスマス前は世界的にソフトウェア製品のリリースラッシュですね。

エンタープライズ版のJava EE 6アプリケーションサーバの最新安定板JBoss EAP 6.2.0がリリースされました。サブスクリプションを購入しているお客様はRed Hatのポータルサイトからダウンロードできます。

詳細は後日公開となるのですが、このリリースからパッチの適用機能が導入され、パッチの適用が簡単になります。今まではパッチは手順書に従って必要なファイル群を置き換えるといういわゆるError proneな手順でしたが、このリリースからパッチの適用はコマンド一発になります。

あと雑多な機能追加がありますがそれらはJBoss EAP 6.2.0 リリースノートを参照してください。

コミュニティ側のダウンロードセクションのほうはだ作業中なのですが、近日中にアップロードされると思います。

14:08:50,776 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) started in 1333ms - Started 129 of 186 services (56 services are passive or on-demand)

追記: 翌日にJBoss EAP 6.2.0がコミュニティ側にも追加されました

JBoss EAP 5.xのフルサポート終了

JBoss / WildFly (全部俺) Advent Calendar 2013の4日目です。流行に乗じて「○○に転職して丸x年が経った」というエントリを書きたいところですがJBossと僕とRed Hatで大体書いてしまっていたのでダメですね。先日テストチームに渡したバグ修正のテスト、再現しないよって言われて調べたら再現確率がパフォーマンスに依存していてマシンかわったりすると再現しないという面倒なヤツでした。詳細ログ出力を有効にすると再現確率が大幅にあがるのでそれで試してもらいます。今日は全てを忘れるjava-ja.忘年会2013です。

エンタープライズ版のJava EE 5アプリケーションサーバであるJBoss EAP 5.xですが、サポートライフサイクルで定められている通り、4年間のフルサポート期間が先月11月で終了しました。

今月からJBoss EAP 5.xはメンテナンスフェーズとなるので、ごく限られたバグ修正と、影響度の高いセキュリティ修正のみの提供となります。その他の雑多なバグは修正されないので、JBoss EAP 5.xを新規の開発などで採用するのは非推奨です。今後はJBoss EAP 6.xを利用してください。

MavenでWildFlyやInfinispanをビルドする

JBoss / WildFly (全部俺) Advent Calendar 2013の3日目です。前にJBoss AS7をビルドするというのを書いたのですが、これをもう少し派生させてみましょう。

お仕事でWildFlyやInfinispanをかなりの頻度でビルドしています。このあたりのプロジェクトはそこそこの規模が大きく、Mavenのマルチプロジェクト構成となっています。Mavenで大きなプロジェクトを効率的にビルドしたりするときに知っておいたほうが良い点がいくつかあります。

まずMavenのオプション設定ですが、~/.bash_profileで以下のように設定しています。スタックサイズ(-Xss)が512kだとInfinispanのビルドでjavacがStackOverflowErrorでコケるので最近1024kに変更しました。メモリも安くなってきてスタックサイズをケチるモチベーションもなくなってきましたし、64bit LinuxでのXssのデフォルトは1024kなのでもうこの定義は消しても良いかもしれません。XmxとMaxPermSizeが十分確保されていれば基本的には問題ないと思います。

export MAVEN_OPTS="-Xmn128m -Xms512m -Xmx4g -XX:MaxPermSize=1g -Xss1024k -Xverify:none -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:+UseCompressedOops"

最初のビルド

最初のビルドは大抵以下のようにして、依存関係の解決、ダウンロードとコンパイルに問題がないことをまず確認します。最初からテストを走らせてそれがコケたりすると依存のダウンロードが後回しになったりしてしまって、待ち時間が細切れになったり、ビルドのトータルの待ち時間が増加します。テストは最初は飛ばしましょう。

mvn -T4 clean install -DskipTests

Mavenのテストをスキップするオプションは二種類あります。もう片方のオプション-Dmaven.test.skipだとテストのコンパイルもあわせてスキップされますが、WildFlyのようにマルチプロジェクト間でテストの依存がある場合それが解決できなくてビルドがコケてしまったりするので、テストもコンパイルはするけどテストの実行はしない、という-DskipTestsを指定しています。

最初の-TオプションはMaven 3の並列ビルドを有効化するオプションです。スレッド数を指定します。CPUコア数に対するスレッド数を指定する1Cという形式でも指定できます。4コアなら1C指定は4と同等です。WildFlyでは4つのMavenプラグインを除き全て並列ビルド対応済みとなっており、並列ビルドでビルドの高速化ができます。並列ビルドだとテストがたまにおかしくなって失敗することがある、-DskipTestsと併用している限り問題ないよ、という情報があったので僕もその通りにしています。

テストも確認

自分でテストを全部通して確認したい場合というのはそれほどないのですが一応。テストの失敗でビルド中断しないように-Dmaven.test.failure.ignoreを指定します。コケるたびにチェックしてもう一回実行してまた待つという作業のは面倒なので通してテストしてしまって後からコケたものだけチェックしたほうがスマートです。WildFlyやInfinispanのテストはかなりリソースを消費するので、MAVEN_OPTSの調整やulimitなどのプロセス数やファイルディスクリプタ数の制限を事前に拡大しておかないとOutOfMemoryErrrorやIOExceptionなどで止まります。

mvn test -Dmaven.test.failure.ignore

一部のビルド

Infinispanはcoreモジュールまでビルドしたい、というようなことがほとんどなので、-pl (projects)にcoreを指定し、合わせて-amを指定して以下のようにビルドします。

mvn -T4 clean install -DskipTests -pl core -am

この-am (also make)オプションは-plで指定したモジュールが依存しているモジュールもビルドする、という指定です。これでcoreモジュールをビルドするための最小のビルドが実行されます。

他に-amd (also make dependents)というオプションがあります。-amはcore*が*依存しているモジュールをビルドするものですが、-amdはcore*に*依存しているモジュールをビルドするオプションです。メソッドシグニチャ変えたときや、定数などコンパイル時に埋め込まれてしまうようなものを変更したときに利用するオプションです。

あとは通しビルドしてて途中でコケた場合に再開する-rf (resume from)オプションがあります。

一部のテスト

バグ修正とかするときにテストするので比較的よく使うやつです。

mvn -pl undertow test -Dtest=UndertowSubsystemTestCase

ビルド/テストマシンを用意する

通しでビルドやテストをするのに自分の作業用ラップトップとかでやるのはあまり賢くないので、できればスペックそこそこなビルドに使えるマシンを別に用意したほうが良いです。

Maven職人の朝は早い。

MavenではじめるJava EE

JBoss / WildFly (全部俺) Advent Calendar 2013の2日目です。ひとつJBoss製品のパッチバイナリをビルドしてテストチームに渡す段取りを終えて一息ついたところです。

Java EE Advent Calendar 2013というのもあるのですが今年も埋まったようで、楽しみです。今日はこちらもJBoss特化ではなくJava EE寄りの話題で。

Java EEのコードをMavenでビルドするときには<dependency>を定義するわけですが、記述方法をGoogle検索すると結構バリエーションが出てきたりして困ったりすることがあります。以下の例ではJava EE 6 にしていますが7でも一緒です。

一番シンプルなのはjavax:javaee-apiを使うものです。

<dependency>
  <groupId>javax</groupId>
  <artifactId>javaee-api</artifactId>
  <version>6.0</version>
  <scope>provided</scope>
</dependency>

Webプロファイル用のjavax:javaee-web-apiというのもあります。

<dependency>
  <groupId>javax</groupId>
  <artifactId>javaee-web-api</artifactId>
  <version>6.0</version>
  <scope>provided</scope>
</dependency>

シンプルでとても良い。と思うかもしれませんがこの依存には実際には罠があります。単体テストを行おうとすると"java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file"とか出力されて単体テストが失敗することがあります。実はこれらの依存で取得できるjarは、全クラスのメソッドボディが削除されている加工されたクラスファイルが格納されています。APIとしての参照、つまりコンパイル時の利用は何も問題はないのですが、実行はできないのです。単体テストなどで実行するには実装側、つまりアプリケーションサーバで提供されるjarファイルが必要になります。知らずにこの依存を採用して途中で地雷踏んだりしないように、踏んでしまって二度手間にならないように、きちんとしたJava EEプロジェクトを作りたい場合は最初から実装サイドで提供されているjarを使うというのが正しいアプローチです。

ちなみに上記のFullとWebのAPI jarはメソッドボディが削られているのでサイズにほぼ差がなく、979KBと930KBです。

さて、JBossで提供しているJava EE APIのjar群はBOM(Bill of materials)でまとめられています。BOMは一連の依存とそのバージョンを定義したもので、いろいろライブラリがあって取捨選択して使うような状況で何のどのバージョン使えばいいの?バージョンの組み合わせは?などと迷わなくて済むように、依存をひとまとまりに定義した特殊なPOMのことです。

BOMを使うにはまず<dependencyManagement>を定義します。バージョンはhttp://search.maven.org/で検索して一番新しいやつを使えば良いです。この例ではWebプロファイルを利用しています。

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.jboss.spec</groupId>
      <artifactId>jboss-javaee-web-6.0</artifactId>
      <version>3.0.2.Final</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencyManagement>を宣言するだけではプロジェクトの依存関係には何も影響はしません。次に実際の<dependency>を記述していきますが、記述する依存はBOMに書いてあるので必要なものをコピーすれば良いです。もちろん最小の依存が定義されているというのが理想な状態ではあるわけですが、面倒だったらとりあえず全部コピーしてしまっても良いと思います。<dependency>を定義するとき、バージョンはBOMで管理されているので記述する必要はありませんし、依存管理を破壊してしまうため基本的には記述してはいけません。Java EEAPIの依存はほぼ<scope>provided</scope>になると思いますが、それはpom.xmlで明記する必要があります。

<dependency>
  <groupId>javax.inject</groupId>
  <artifactId>javax.inject</artifactId>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>javax.enterprise</groupId>
  <artifactId>cdi-api</artifactId>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.jboss.spec.javax.ws.rs</groupId>
  <artifactId>jboss-jaxrs-api_1.1_spec</artifactId>
  <scope>provided</scope>
</dependency>

MavenリポジトリにはグループIDがorg.jboss.javaeeのものやorg.jboss.spec:jboss-javaee_6.0_specという名前が似ている紛らわしいものも見つかると思いますが、これはBOMになる前の古いものなので無視してください。

JBoss / WildFly Advent Calendar 2013

JBoss / WildFly (全部俺) Advent Calendar 2013の1日目です。

アウトプット作れないプロなんてただのうんこなのでアウトプットどんどんしましょう、Advent Calendarというちょうどいいのがあるじゃない、ということではじめた全部俺Advent Calendarですが今年もゆるゆるで3年目です。基本的にお仕事時間に書く、土日の分は平日のどこかで、遅れても気にしないという感じでやってます。アウトプットしないと便秘になっちゃうので健康に良くない。

初めて見る人は誰がこれ書いてんの?って思うでしょうから初日はそのへんをざらっと。

Red Hatのサポート部門でSenior Software Maintenance Engineerしてます。お客様からのサポートリクエストのうち難しいものを解決するであるとか、JBoss関連プロジェクトのバグ修正とかをやっています。最近だとKazuhiraさんがInfinispanのcapacityFactorが適用されないバグについてblogで解説していたので修正飛ばしたりしました。これももちろん仕事の一部です。Emacs使いで、EclipseとかNetBeansとかIntelliJ IDEAとかごてごてしたGUIを持つIDEが苦手です。Javaが一番詳しいですが普段のお仕事ではテストクライアントのような細かいプログラムを書くことが多いのでJRubyを好んで使います。

ちょっと長めの自己紹介とか仕事内容っぽいやつは過去に書いたのでリンク置いておきます。

今年もよろしく。

WildFly / JBoss EAPの2013/11時点での現状

GlassFish v4の商用サポートないよロードマップの発表に伴ってWildFlyJBoss EAPに少し注目が集まっているようなので、WildFlyJBoss EAPの現状をざっくりと整理しておきます。

JBoss AS7 / WildFly 日本語版FAQというのも前に書いたので合わせてどうぞ。

WildFly / JBoss EAPJava EE関連、その他Red Hat関連のお仕事に関する履歴書の送り先などはRed Hat Jobsをどうぞ。