Live By The Code

元業務系プログラマの呟き

移転しました

現在は以下のURLで書いています.
http://www.nailedtothex.org/roller/

WildFly8でサーブレットを動かしてみる

Eclipseサーブレットを書いてWildFly8にデプロイしてみます。

JavaEE7のプロジェクトを作る

新しいMavenプロジェクトを作ってJavaEE7のarchetypeを探しますがEE6のものしか見つかりません。
f:id:lbtc_xxx:20140116180634p:plain

ここにJavaEE7用の何かが存在するようなのでこれを使ってみたかったのですが、やり方がよくわかりませんでした...。仕方が無いので替わりになりそうなものを使います。「Configure」→「Add Remote Catalog」から新たなカタログ http://repo1.maven.org/maven2 を追加します。
f:id:lbtc_xxx:20140116180721p:plain

もとの画面に戻ったら「javaee7」と入れてみます。すると「javaee7-essentials-archetype」というのが現れるのでこれを使って進めます。Nextを押すとしばらく何かのダウンロードが行われます。
f:id:lbtc_xxx:20140116180751p:plain

適当に入力してFinish
f:id:lbtc_xxx:20140116180808p:plain

右下に表示される処理中インジケータを眺めながらしばらく待つとプロジェクトが出来上がります。
f:id:lbtc_xxx:20140116180825p:plain

サーブレットを作る

もはや何でも良いので超適当に

package com.example;
 
import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("Hello world");
    }
}

デプロイ

ServersのViewを開いてWildFlyを右クリックし「Add and Remove」を選びます
f:id:lbtc_xxx:20140116181011p:plain

次に現れるウインドウで、つい先ほど作ったJavaEE7Pracを選択してAddを押して右側に移しFinishを押します
f:id:lbtc_xxx:20140116181028p:plain

Consoleを見るとデプロイできました的なメッセージが出ているはず。確認したらブラウザで表示してみます。
f:id:lbtc_xxx:20140116181136p:plain

自動デプロイさせる

htmlファイルなどはデフォルトで自動的に反映されるのですが、クラス等は追加の設定を入れないと自動デプロイが走りません。

  1. Serversを開きます
  2. WildFlyをダブルクリックします
  3. 画面下部の「Deployment」を選びます
  4. Deploy project as compressed archivesにチェックを入れます

f:id:lbtc_xxx:20140116181209p:plain

それでは自動デプロイの実験をしてみます。こんな感じに編集して保存してみます。びっくりマーク追加しただけです。
f:id:lbtc_xxx:20140116181233p:plain
保存してからコンソールを眺めているとデプロイしました的な文言が流れます。

ブラウザでリロードすると表示が変わり資源が更新されたことがわかります。
f:id:lbtc_xxx:20140116181256p:plain

WildFly8.0.0CR1をEclipseから起動してみる

WildFlyとは?

いわゆるアプリケーションサーバです。WildFly8はJavaEE7準拠です。

EclipseJBoss Toolsを入れる

WildFlyはNetBeans7.4では使えないようなので(NetBeans8から使えるようになる模様)Eclipseを使います。私はeclipse-jee-kepler-SR1-macosx-cocoa-x86_64.tar.gzというやつを取って来ました。

Macの場合は、コンソールの日本語が?に化けるのを防ぐために、Eclipseを展開したらこの作業をやっておきましょう。

起動したらメニューからHelp→Eclipse MarketPlaceを開き「jboss」で検索すると「JBoss Tools (Kepler) 4.1.1.Final」というのが出てくるので、それをインストールします。Confirm Selected Featuresとかいう山ほどチェックボックスが出てくるダイアログとか表示されたりするけど特に気にせずデフォルトのまま次へ次へとやっていきます。

WildFlyを入れる

ダウンロードはここから。私は wildfly-8.0.0.CR1.tar.gzというやつを取ってきました。

  1. wildflyを適当なところに展開する
  2. Eclipseのウェルカム的な画面を閉じる
  3. Window→Show View→Serversを開く
  4. サーバが無いから作れや的なリンクをクリックする
  5. WildFly 8.0 (Experimental)を選んでNext
  6. WildFlyを展開したディレクトリを入力してFinish。こんな感じ

f:id:lbtc_xxx:20140116175730p:plain

起動してみる

「Servers」にWildFlyが現れたら右クリックメニューからStartしてみましょう。
f:id:lbtc_xxx:20140116180115p:plain

2915msとなかなか速いですね。ついでにブラウザからアクセスしてみましょう。
f:id:lbtc_xxx:20140116180145p:plain

ちゃんと動いているようですね。

jbatchのジョブ管理用DBについて

ジョブ管理用DBとは

jbatchでは、実行したジョブについて以下のような情報が履歴として残るようになっている。

  • ジョブプロパティ
  • ジョブの開始時刻、終了時刻、終了ステータス
  • 各ステップの処理件数、開始時刻、終了時刻、終了ステータス

履歴として随時参照できる他、このような情報を保持することで、異常終了したジョブの再実行の際、正常に終了したステップやチャンクについては処理をスキップし、まだ処理が終わっていないチャンクから処理を再開する、といった事が出来るようになっていたりする。

履歴の確認方法

Webの管理コンソールから確認する方法の他に、CLIのasadminコマンドから確認することもできる。後者の方が軽いので、慣れてきたら基本的には後者を用いるのが良いだろう。

  • 管理コンソールを開き、左サイドバーの「サーバー(管理サーバー)」を選択後「バッチ」タブを選択
  • asadminのlist-batch-jobs, list-batch-job-steps, list-batch-job-executionsコマンドを使う

ジョブ管理用DB用データソースの確認/変更方法

GlassFish4付属の実装の場合、デフォルトでは埋め込みDerbyに保持するようになっている。データソース名は以下コマンドで確認できる。

$ ./asadmin list-batch-runtime-configuration
DATASOURCELOOKUPNAME  EXECUTORSERVICELOOKUPNAME                   
jdbc/__TimerPool      concurrent/__defaultManagedExecutorService  
Command list-batch-runtime-configuration executed successfully.
$ 

変更する場合は以下コマンド(データソースjdbc/__defaultに変更する例)。

./asadmin set-batch-runtime-configuration --datasourcelookupname jdbc/__default

またWebの管理コンソールからも確認および変更が可能。左サイドバーの「サーバー(管理サーバー)」を選択後「バッチ」タブを選択、さらに「構成」タブを選択すると変更画面が現れる。

ジョブ管理用DBを変更する場合における注意点など

JDBC接続プール定義

JDBC接続プールを定義する際「リソース・タイプ」は「javax.sql.XADataSource」を選択する。

「javax.sql.DataSource」を選んでしまうと、ジョブ実行時に以下のような例外が発生して正常に動作しない。

SQLException: 接続の割当でエラーが発生しました。
原因: java.lang.IllegalStateException: ローカル・トランザクションには、すでに1つの非XAリソースがあります: これ以上リソースを追加できません。

必要なテーブル等の準備

Derbyの場合は必要なテーブル等が存在していなければ自動的にDDLを流してくれるようになっているが、他のDBの場合はDDLを手動で流してやる必要がある。/glassfish-4.0/glassfish/lib/install/databases に各種RDB用のものが存在するのでそれを使えば良いようだ。ただし…

Derby以外はテストされていない?

前述のDDLを使いPostgreSQLに変更する事を試みたが、テーブルを作った後いざジョブを実行すると、フレームワーク側で実行するSQL文の構文エラーとなり正常に動作しなかった。他のDBでは検証していないが、今のところDerby以外での動作は確認できていない。

意外に負荷が高い

step要素内でchunk要素を使っている場合、コミットの度にblobのUPDATEが走るため意外に負荷が高い(おそらくcheckpointを記録していると思われる)。

ジョブ履歴を確認するためにはasadminコマンドか管理コンソールを使うが、これが履歴の件数に比例してどんどん重くなるため、Derbyをサーバモードにして直接テーブルを覗けないかと考えたのだが、前述の通りの重いクエリが頻繁に走るため、埋め込みモードに比べてパフォーマンス劣化がかなり大きくなってしまう。

手元のあるバッチでは起動から終了までに3倍の時間がかかるようになってしまい堪え難いので、個人的には、落としどころとして、埋め込みDerbyをジョブ管理用DBとして使い履歴がある程度溜まったら定期的にテーブルを掃除する運用にしている。

この際、GlassFish4のデフォルトではEJBタイマ用データソースと同じデータソースに設定されているので、これを別途新しく定義したバッチ管理用データソースに変更しておき、埋め込みDerbyのディレクトリごと退避してしまう運用にすれば手間がかからない。

undeployすると履歴は消去される?

基本的にはアプリケーションをundeployすると履歴は全て消去されるようになっているが、消去されない場合もあるようだ。どのような条件で消去されるのか、されないのかは不明である。

jbatchのトランザクションのタイムアウト

jbatchではデフォルトでトランザクションに180秒のタイムアウトが設定されており、タイムアウトを超えると例外が発生してバッチが異常終了するようになっている。

発生する例外は以下のような感じ。

com.sun.appserv.connectors.internal.api.PoolingException: 
javax.transaction.RollbackException 

そもそもそんなにトランザクションが長くなるバッチは設計上如何なものか、という検討も必要かもしれないが、とりあえずタイムアウトする秒数はstep要素のjavax.transaction.global.timeoutプロパティで制御できる。

0を指定すればタイムアウト無しになるようだが

The value of the timeout in seconds. If the value is zero,
     *        the transaction service restores the default value. If the value
     *        is negative a SystemException is thrown.

javadocにこんな風に書かれているので止めたほうが無難かも

ジョブ定義XMLへの記載例は以下のようになる。

<step id="step1">
    <properties> 
        <property name="javax.transaction.global.timeout" value="0"/> 
    </properties>
    <chunk>
      ...
    </chunk>
</step>

Mac(MacBook 2009-Mid ポリカーボネート)へ、OS X 10.8 Mountain Lionをクリーンインストール

少し古めのMac(MacBook 2009-Mid ポリカーボネートOS X 10.5 Leopard搭載)へ、OS X 10.8 Mountain Lionをクリーンインストールしてみる。

大まかな手順は以下の通り。

  1. 10.6 Snow Leopardクリーンインストール(AppleのオンラインストアでDVD媒体にて購入可能。1,700円)
  2. ソフトウェアアップデートでSnow Leopardを10.6.8まで更新
  3. App Storeで10.8 Mountain Lionを購入(ダウンロードで購入可能、1,700円)・インストール

10.5 Leopardから最新版まで更新するには合計3,400円が必要となる。

10.6 Snow Leopardクリーンインストール

HDDが空の場合、電源を入れた後にSnow LeopardのDVDを挿入すればインストーラが起動する。その後表示されるインストール画面で「ディスクユーティリティ」を実行し、パーティションを作成する。

以下参考
http://support.apple.com/kb/HT3200?viewlocale=ja_JP

パーティションの作成以外は、画面の指示に従って進めて行けば特に問題無い。

ソフトウェアアップデート

Snow LeopardのDVDからのインストール直後にはアップルメニューの選択肢にAppStoreが存在しないが、ソフトウェアアップデートで10.6.8まで更新するとAppStoreが選択肢に現れる。

Mountain LionをApp Storeで購入

ソフトウェアアップデート後に、アップルメニューからApp Storeを起動し、検索欄にMountain Lionと入力すると一覧に現れる。

購入すると、そこからはダウンロードからインストールまで自動的に行われる。

メモリ増設

この機種は非公式ながら4GB×2の合計8GB構成までメモリ増設が可能なので、ページングが発生するようであれば増設を検討したい。

Mac(MacBook 2009-Mid ポリカーボネート)の掃除

出荷時にはOS X 10.5 Leopardがプリインストールされていたが、現在ではサポートも切れており、しばらく使う事なく放置していたが、現在のOS Xの最新版10.8の動作対象機種に含まれているとの事なので、HDDを交換してクリーンインストールし、再度使ってみる事にした。

内部の掃除

1年ほどロクに使わず放置していたが、3年ほどは稼動しており、何か作業するとすぐにファンが回転して煩かったため、まず内部の掃除をする事にした。

必要なもの

  • クレジットカード程度の厚さのカード : キーボードを基盤から取り外す際「ヘラ」のように使う
  • 精密ドライバー
  • トルクスドライバー(T8) : HDDをマウンタから取り外すのに使う。掃除だけなら特に必要ない
  • エアダスター

分解の手順

分解する手順は以下が参考になる。少し機種が違うが同じ構造である。水洗いは止めておく。

http://nomiandaska.net/top/20120305/macbook_white_dissolution/

注意点

前述のエントリと重複する部分もあるが、注意しておきたい点は以下。

  • ネジは場所毎に異なるので、どこの穴のネジだったか忘れないように
  • HDDは白い取っ手を持って引っ張り出す
  • メモリはレバーを引けば外れる
  • キーボードやパームレストはとても壊れ易いので、取り外す際は慎重に(筆者は若干パームレストの端を破壊してしまった)
  • ネジを全て外し終えると、電源プラグ差し込み口からヒンジのあたりにかけてカードを差し込む隙間ができるので、そこに差し込んで少しずつ慎重に外していく
  • 光学ドライブ横の部分を固定しているプラスチックのパーツが若干外れにくいので慎重に
  • キーボードと基盤を繋いでいる短いケーブルに注意。取っ手が付いているので、慎重に垂直方向に持ち上げて外す

分解後

キーボードを外したら、エアダスターで基盤部分の埃を吹き飛ばす。CPUファン周辺は重点的に。

HDDは2.5インチのSATAドライブで、厚さ9.5mmのものを選ぶ。筆者はHGST製の500GBのものに交換した。引き出したHDDに付いているマウンタをトルクスドライバで外し、新しいHDDに装着して元の位置に押し込めばOK。