<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>トラシスラボ 技術ブログ</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/" />
    <link rel="self" type="application/atom+xml" href="http://trasis.jp/blog/lab/atom.xml" />
    <id>tag:trasis.jp,2008-02-27:/blog/lab//2</id>
    <updated>2010-08-12T07:07:50Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Open Source 4.1</generator>

<entry>
    <title>PostgreSQLでテーブルのファイルサイズを確認する</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2010/08/postgresql-check-table-filesize.html" />
    <id>tag:trasis.jp,2010:/blog/lab//2.180</id>

    <published>2010-08-12T07:04:49Z</published>
    <updated>2010-08-12T07:07:50Z</updated>

    <summary> SELECT   relname,   relkind,   to_char(...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="PostgreSQL" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<pre class="code2">
SELECT
  relname,
  relkind,
  to_char(reltuples, '999,999,999') as rows,
  to_char(pg_relation_size(relname), '999,999,999,999') as bytes
FROM pg_class
WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname='public')
order by bytes desc;
</pre>

<h2>参考</h2>

<a href="http://d.hatena.ne.jp/y-kawaz/20090226/1235623336">PostgreSQLでテーブルサイズを確認する</a> by y-kawaz<br />]]>
        
    </content>
</entry>

<entry>
    <title>StringBuilder に1文字追加する時の性能差</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2010/07/stringbuilder-append-performance.html" />
    <id>tag:trasis.jp,2010:/blog/lab//2.179</id>

    <published>2010-07-13T07:39:26Z</published>
    <updated>2010-07-13T07:47:32Z</updated>

    <summary> 概要 StringBuider で append() を使い１文字を追加すると...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="Java" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[
<h2>概要</h2>

StringBuider で append() を使い１文字を追加するとき、<br />
<pre class="code2">
sb.append('\t');
</pre>
のように char 型を追加するときと<br />
<pre class="code2">
sb.append("\t");
</pre>

のように文字列型で追加するときに性能差を調査した。<br />
<p />

<h2>結果</h2>

<table class="mytable">
<tr>
	<th>追加データ</th><th>実行時間 [s]</th>
</tr>
<tr>
	<td>'\t'</td>
	<td>2.165</td>
</tr>
<tr>
	<td>"\t"</td>
	<td>7.788</td>
</tr>
</table>

<p />
１つの文字を追加する場合は、 char 型で追加したほうが文字列で追加するより 3.6 倍高速だった。<br />]]>
        
    </content>
</entry>

<entry>
    <title>PostreSQLでJavaのミリ秒をtimestamp型で取り出す</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2010/07/java-timeinmillis-to-timestamp.html" />
    <id>tag:trasis.jp,2010:/blog/lab//2.178</id>

    <published>2010-07-05T09:01:00Z</published>
    <updated>2010-07-05T09:15:01Z</updated>

    <summary>概要 PostgreSQL 上に作成したテーブルに対し、Java で時刻を ti...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="PostgreSQL" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="postgresql" label="postgresql" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="tomcat" label="tomcat" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h2>概要</h2>

PostgreSQL 上に作成したテーブルに対し、Java で時刻を timestamp 型ではなくミリ秒(long 値)のまま格納した場合、それを select で timestamp 型として取り出すには以下のように SQL を記述する。

<pre class="code2">
SELECT
    (lastaccess / 1000) :: text :: interval + '1970-01-01' :: timestamp
FROM
    table1;
</pre>

lastaccess は bigint 型のカラム。これを1000分の1して秒単位にし、 epoch 秒（グリニッジ標準時間1970年1月1日00:00:00からの経過秒数）　に足している。

<h3>例: DB に格納された tomcat のセッションでサイズの大きいものを見つける</h3>

次のような SQL を実行する。

<pre class="code2">
SELECT
	length(data) as len,
	session_id,
	(lastaccess / 1000) :: text :: interval + '1970-01-01' :: timestamp
FROM
	tomcat_sessions
ORDER BY len desc
LIMIT 20;
</pre>]]>
        
    </content>
</entry>

<entry>
    <title>Windows7でEclipse利用時、ツリービューが自動スクロールするのを止める方法(64bit版でもOK!)</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2010/01/windows7-eclipse-disable-automatic-scrolling.html" />
    <id>tag:trasis.jp,2010:/blog/lab//2.173</id>

    <published>2010-01-19T08:45:05Z</published>
    <updated>2010-01-19T09:39:26Z</updated>

    <summary>概要 Windows7で Eclipse 3.3 を動作したときに「パッケージ・...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
    <category term="eclipse" label="eclipse" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="windows7" label="Windows7" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>概要</h3>

Windows7で Eclipse 3.3 を動作したときに「パッケージ・エクスプローラ」ビューが自動的に横スクロールするのを停止する方法について説明。<br />
32bit,  64 bit 環境の違いなく簡単に解決できるので便利。<br />
多分 Vista でも同じ方法で解決する。<br />
<br />

<h3>背景</h3>
Windows7(と Vista)でEclipseを利用時、イライラする現象がある。<br />
<br />
画面左側の「パッケージ・エクスプローラ」ツリービューにおいて、深いパッケージ階層にアクセスしている時に、<b>勝手に横スクロールする</b>。<br />
<br />
<img src="http://trasis.jp/blog/lab/2010/01/19/windows7-eclipse-1.png" /><br />
<br />
十分な横幅の画面で作業していれば、このビューを横に広げてこの問題を回避できるが...。<br />
<br />
この<b>新たな機能</b>は Windows Vista からツリービューに搭載されたものらしい。。。<br />
せめて挙動を選択できるようにして欲しかった。<br />
<br />

<h3>32bit ユーザなら Explorer Construction で!</h3>

<a href="http://chihiro718.jpn.org/JPN/software/help/ExpConst/option.htm">Explorer Construction</a>というツールを使うことで、この横スクロールを無効化できるらしい。<br />
<br />
ソフト起動後、「水平方向の自動スクロールを無効にする(A) 」にチェックを入れるだけ。<br />
残念ながら 64bit 環境では動作しない。本当に残念...。<br />
<br />

<h3>Windows 互換モードで実行することで 64bit でも解決!</h3>

しばらく探しまわって、やっと解決法を見つけた。 ⇒<a href="http://www.vistax64.com/vista-general/133849-disable-dynamic-horizontal-scrolling-vista.html">disable dynamic horizontal scrolling in Vista</a><br />
<br />
内容は簡単。「<b>Eclipse を Windows XP 互換モードで動かすだけ</b>」でした。<br />
<br />
Eclipse のショートカットを作成し、プロパティを表示。
「互換性」タブで「互換モードでこのプログラムを実行する」にチェックを入れ、
「Windows XP (Service Pack 3)」を選択するだけでよい。<br />
<br />
<img src="http://trasis.jp/blog/lab/2010/01/19/a.png" /><br />
<br />
この方法は Eclipse だけでなく他のアプリケーションでも適用できる。
]]>
        
    </content>
</entry>

<entry>
    <title>PostgreSQLで現在ロック中のプロセスの確認とkill</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2009/10/postgresql-kill-lock-process.html" />
    <id>tag:trasis.jp,2009:/blog/lab//2.122</id>

    <published>2009-10-16T01:27:33Z</published>
    <updated>2009-10-16T01:48:05Z</updated>

    <summary>概要 PostgreSQLの各プロセスがどのテーブルでどの種類のロックを行ってい...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="PostgreSQL" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>概要</h3>

PostgreSQLの各プロセスがどのテーブルでどの種類のロックを行っているか調べる方法について説明。<br />
<br />
さらに、そのプロセスを下記手順で終了することで、ロックしていた処理を強制的に中断できる。

<h3>手順</h3>

<h4>プロセスIDの確認</h4>

コマンドラインなどで、次のSQLを実行する。

<pre class="code2">
SELECT l.pid, db.datname, c.relname, l.locktype, l.mode
FROM pg_locks l
        LEFT JOIN pg_class c ON l.relation=c.relfilenode
        LEFT JOIN pg_database db ON l.database = db.oid
ORDER BY l.pid;
</pre>

pid がプロセスIDを意味する。

<h4>プロセスの停止</h4>

プロセスIDが分かったら、次のSQLでプロセスを停止できる。<br />

<pre class="code2">
SELECT pg_cancel_backend(<font color="red">プロセスID</font>);
</pre>
]]>
        
    </content>
</entry>

<entry>
    <title>snmpでtomcat メモリを監視 (Linux編)</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2009/08/snmpでtomcat-メモリを監視-linux編.html" />
    <id>tag:trasis.jp,2009:/blog/lab//2.106</id>

    <published>2009-08-05T04:02:06Z</published>
    <updated>2009-08-24T05:50:16Z</updated>

    <summary>概要 前回 は、Windows 上で起動した Java　プロセスを snmp で...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="tomcat" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="snmp" label="snmp" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>概要</h3>

<a href="http://trasis.jp/blog/lab/2009/08/snmp%E3%81%A7java%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%82%92%E7%9B%A3.html">前回</a> は、Windows 上で起動した Java　プロセスを snmp で監視する方法を説明した。<br />
<br />
今回は Linux 上で起動した Tomcat プロセスのメモリを監視する方法について説明する。<br />

<h4>動作環境</h4>

<table class="mytable"><tbody>
<tr>
	<th>項目</th><th>値</th>
</tr>
<tr>
	<td>OS</td>
	<td>CentOS 5</td>
</tr>
<tr>
	<td>Java</td>
	<td><a href="http://java.sun.com/javase/ja/6/download.html">JDK 6 update 10</a></td>
</tr>
<tr>
	<td>Tomcat</td>
	<td>6.0.20</td>
</tr>
</tbody></table>

<h3>tomcat 起動時の設定</h3>

Tomcat を起動する時の CATALINA_OPTS 変数に次の記述を追加する。<br />
例えば、/etc/tomcat6/tomcat6.conf で次のように記述する。<br />

<div class="code2">
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.snmp.port=1161 -Dcom.sun.management.snmp.acl.file=/etc/tomcat6/snmp.acl"
</div>

<h3>/etc/tomcat6/snmp.acl 作成</h3>

ファイルを作成する。

<pre class="code2">
acl = {
 {
   communities = public
   access = read-only
   managers = localhost
 }
}
</pre>

さらに、snmp.acl のパーミッションを 600 に変更する。<br />

<pre class="code2">
# chown roo:root snmp.acl
# chmod 600 snmp.acl
</pre>

ここまで設定が終わったら、Tomcat を起動する。

<div class="code2">
# service tomcat6 start
</div>

<h3>MIB ファイルを置く</h3>

/usr/share/snmp/mibs/JVM-MANAGEMENT-MIB.mib を作成する。<br />

<div class="code2">
# cd /usr/share/snmp/mibs/<br />
# lftpget http://java.sun.com/j2se/1.5.0/docs/guide/management/JVM-MANAGEMENT-MIB.mib
</div>

<h3>/etc/snmp/snmp.conf 設定</h3>

次に snmpd の設定。このファイルの最後へ記述を追加する。

<div class="code2">
proxy -m /usr/share/snmp/mibs/JVM-MANAGEMENT-MIB.txt -v 2c -c public localhost:1161 .1.3.6.1.4.1.42.2.145
</div>

記述を追加したら、snmpd を再起動する。
<div class="code2">
# service snmpd restart
</div>

<h3>動作確認</h3>

<div class="code2">
$ snmpwalk -v 2c -c public localhost .1.3.6.1.4.1.42.2.145
</div>

<h4>出力結果をカスタマイズ</h4>

数字で構成される OID 値を文字列に変更できる。<br />
上記の手順で mib ファイルを snmpwalk を実行するホストに置いた後、次のように環境変数を設定する。<br />
.bashrc などに書いておくとよい。

<div class="code2">
$ export MIBS=ALL<br />
$ snmpwalk -v 2c -c public localhost .1.3.6.1.4.1.42.2.145
</div>

<h3>参考</h3>

<ul>
<li><a href="http://www.gentoo-wiki.info/JVM_Monitoring_with_SNMP">
http://www.gentoo-wiki.info/JVM_Monitoring_with_SNMP</a></li>
<li><a href="http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/management/snmp.html">http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/management/snmp.html</a>
</ul>
]]>
        
    </content>
</entry>

<entry>
    <title>snmpでtomcatメモリを監視(Windows編)</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2009/08/snmpでjavaプロセスを監.html" />
    <id>tag:trasis.jp,2009:/blog/lab//2.105</id>

    <published>2009-08-04T03:13:20Z</published>
    <updated>2009-08-11T03:35:35Z</updated>

    <summary>概要 Javaでwebサイトを運用し、ある程度規模が大きくなってくるとメモリ管理...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="Java" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="java" label="java" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="snmp" label="snmp" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>概要</h3>

Javaでwebサイトを運用し、ある程度規模が大きくなってくるとメモリ管理で悩まされる。<br />
安定、高速なwebサイトを目指すためにはメモリ関連のモニタリングとチューニングが必要になってくる。<br />
<br />
ガベージ・コレクション関連のログ出力設定を行う方法は簡単だが、nagios などで監視を行い、閾値に達したらアラート・メールで通知してくれると便利である。<br />
<br />
今回は Java の snmp 監視を有効にする設定手順について説明する。

<h4>開発環境</h4>

<table class="mytable">
<tbody><tr>
	<th>項目</th><th>値</th>
</tr>
<tr>
	<td>OS</td>
	<td>Windows XP Pro SP3</td>

</tr>
<tr>
	<td>IDE 環境</td>
	<td><a href="http://mergedoc.sourceforge.jp/index.html">Eclipse 3.4.1(Preiades All in One)</a></td>
</tr>
<tr>
	<td>Java</td>
	<td><a href="http://java.sun.com/javase/ja/6/download.html">JDK 6 update 10</a></td>
</tr>

</tbody></table>


<h3>Windows 環境での設定手順</h3>

<h4>概要</h4>

Windows 上で起動中の Eclipse から Java プログラムを起動し、そのプロセスを snmp で監視できるよう、設定を行う。

<h4>プログラム例</h4>

次のようなプログラムを作成した。

<pre class="code2">
public class Test {
	public static void main(String[] args) throws InterruptedException {
		int count = 0;
		
		for (;;) {
			Thread.sleep(1000);
		
			count++;
			System.out.println(count);
		}
	}
}
</pre>

とりあえず１回実行してみる。<br />
[実行] メニュー ⇒ 実行 ⇒ Java アプリケーション<br />
<img src="http://trasis.jp/blog/lab/2009/08/04/snmp-windows/1.PNG" />

<h4>起動オプション設定</h4>

1回実行した後、今度は実行構成を開く。<br />
[実行] メニュー ⇒ 実行構成<br />
<img src="http://trasis.jp/blog/lab/2009/08/04/snmp-windows/2.PNG" /><br />

<br />
[引数] タブを選択し、「VM引数」のところに次の文字列を入力する。
<div class="code2">
-Dcom.sun.management.snmp.port=161 -Dcom.sun.management.snmp.acl.file=c:/snmp.acl -Dcom.sun.management.config.file=c:/management.properties
</div>
<img src="http://trasis.jp/blog/lab/2009/08/04/snmp-windows/3.PNG" />

<h4>設定ファイルのコピー</h4>

次に、<code>C:\Program Files\Java\jre6\lib\management</code> の下にある、次の２つのファイルを C:\ にコピーする。
<ul>
 <li> management.properties</li>
 <li> snmp.acl.template</li>
</ul>

<code>snmp.acl.template</code> は snmp.acl に名前を変える。

<h4>設定ファイルの修正</h4>

<h5>c:\snmp.acl</h5>

ホスト 172.16.1.2 からコミュニティ名「public」で snmp 読み込みを受け付ける場合は、次のように記述する。

<pre class="code2">
   acl = {
     {
       communities = public
       access = read-only
       managers = 172.16.1.2
     }
    }
 </pre>

<h5>c:\management.properties</h5>

Java 起動時、デフォルト設定では localhost で 161 ポートを listen する。別のホストから snmp を受け付けるには、次のように Java プログラムを起動するホストの IP アドレスを設定する。

<pre class="code2">
com.sun.management.snmp.interface=172.16.1.3
</pre>

<h4>アクセス権の修正</h4>

エクスプローラで c:\snmp.acl 上で右クリック、[プロパティ] を選択する。<br />
<img src="http://trasis.jp/blog/lab/2009/08/04/snmp-windows/4.PNG" /><br />
<br />
[セキュリティ] タブを開き、[詳細設定] ボタンを押す。<br />
<br />
「子オブジェクトに適用するアクセス許可エントリを親から継承し、それらをここで明示的に定義されているものに含める」についているチェックを外す。<br />
<br />
「アクセス許可エントリ」から、自分の名前以外を全て削除する。<br />
Administrator や他のユーザからのアクセス権が残っていると、Java プログラム起動時に次のようなエラーメッセージが出てしまう。
<div class="code2" style="color: red; font-weight: bold">
エラー: パスワードファイルの読み取りアクセスは制限する必要があります。: c:/snmp.acl
</div>

<br />
これで準備完了。<br />
サンプルプログラムを起動したあと、snmp アクセスを許可したホスト(上記の例だと 172.16.1.2) から次のようにアクセスしてみる。

<pre class="code2">
$ snmpwalk -v 2c -c public 172.16.1.3 .1 -On | less
</pre>

次のような内容が出力される。

<pre class="code2">
.1.3.6.1.4.1.42.2.145.3.163.1.1.1.1.0 = Gauge32: 729
.1.3.6.1.4.1.42.2.145.3.163.1.1.1.4.0 = INTEGER: 1
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.1.0 = Gauge32: 0
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.2.0 = INTEGER: 1
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.3.0 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.100.1.2.1 = STRING: "CodeCacheManager"
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.100.1.2.2 = STRING: "Copy"
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.100.1.2.3 = STRING: "MarkSweepCompact"
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.100.1.3.1 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.100.1.3.2 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.100.1.3.3 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.2.1 = STRING: "Code Cache"
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.2.2 = STRING: "Eden Space"
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.2.3 = STRING: "Survivor Space"
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.2.4 = STRING: "Tenured Gen"
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.2.5 = STRING: "Perm Gen"
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.2.6 = STRING: "Perm Gen [shared-ro]"
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.2.7 = STRING: "Perm Gen [shared-rw]"
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.3.1 = INTEGER: 1
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.3.2 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.3.3 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.3.4 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.3.5 = INTEGER: 1
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.3.6 = INTEGER: 1
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.3.7 = INTEGER: 1
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.4.1 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.4.2 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.4.3 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.4.4 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.4.5 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.4.6 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.4.7 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.112.1 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.112.2 = INTEGER: 1
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.112.3 = INTEGER: 1
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.112.4 = INTEGER: 2
.1.3.6.1.4.1.42.2.145.3.163.1.1.2.110.1.112.5 = INTEGER: 2
...
</pre>


なお、-v で指定する SNMP バージョンは 2c を指定する必要がある。<br />
1 だと、heap 値を取得できない。<br />

<h3>参考情報</h3>

Sun から提供されている以下のドキュメントを参考。
<ul>
<li> <a href="http://java.sun.com/j2se/1.5.0/docs/guide/management/SNMP.html">SNMP Monitoring and Management</a></li>
<li> <a href="http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/management/security-windows.html">Windows 用のセキュリティ情報の詳細</li>
</ul>
]]>
        
    </content>
</entry>

<entry>
    <title>DSR(Direct Server Return)メモ</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2009/06/direct-server-return.html" />
    <id>tag:trasis.jp,2009:/blog/lab//2.101</id>

    <published>2009-06-02T17:03:12Z</published>
    <updated>2009-06-02T17:22:17Z</updated>

    <summary>概要 BIG-IP + Linux 2台(CentOS 5) で DSR(Dir...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="ネットワーキング" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="dsr" label="DSR" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h2>概要</h2>

BIG-IP + Linux 2台(CentOS 5) で DSR(Direct Server Retrun) 構成を行ったときの設定メモ。<br />

<h2>DSRとは</h2>

<a href="http://nosa.cocolog-nifty.com/sanonosa/2004/11/l4dsr.html">こちらの記事</a>が分かりやすい。<br />
この記事にあるように、このままだと　mac アドレスがあちこちにキャッシュされてしまい、いろいろ問題が出て少々やっかいだった。<br />
<br />
次のように iptables と組み合わることで、簡単にこの問題を解決できる。

<h2>バックエンド設定</h2>

Linux サーバの /etc/sysconfig/iptables に対し、次の設定を行う。

<pre class="code2">
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

COMMIT

# =================================================================
*nat

-A PREROUTING -p tcp -d 172.16.100.1 -j REDIRECT

COMMIT
</pre>

172.16.100.1 はロードバランサで設定した VIP アドレス。<br />

]]>
        
    </content>
</entry>

<entry>
    <title>seasar2+hibernate+JPA(1.0)環境における悲観的ロック</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2009/05/jpa10における悲観的ロック.html" />
    <id>tag:trasis.jp,2009:/blog/lab//2.97</id>

    <published>2009-05-18T16:37:08Z</published>
    <updated>2009-05-18T17:50:08Z</updated>

    <summary>背景 - ロック手法について データベース更新時のロックの方法として、次の２種類...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="Java" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="PostgreSQL" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="hibernate" label="hibernate" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="jpa" label="jpa" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="seasar2" label="seasar2" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>背景 - ロック手法について</h3>

データベース更新時のロックの方法として、次の２種類が存在する。

<ul>
<li> 悲観的ロック (Pessimistic lock)</li>
<li> 楽観的ロック (Optimistic lock)</li>
</ul>

<b>悲観的ロック</b>は、更新対象を更新完了までロックし、他の人が更新を行ったり、場合によっては参照も禁止する方法。<br />
データをより安全に更新・参照できるメリットがあるが、ロック待ちによるアプリケーションの性能低下要因となりやすい。<br />
<br />
<b>楽観的ロック</b>は「自分が操作している情報は他人が同時に更新する可能性が低い」更新を行うのに向いたロック方法。<br />
更新対象を本当に更新する段階までぎりぎりまでロックしない。<br />
<br />
例えば、「一旦データを取得したあと、内容を変更して実際に変更しようとしたら、データ取得後に誰かが同じレコードを更新していた」というケースの場合、悲観的ロックであれば「データ取得時に行ロックを行い、誰も更新できない状況」を作ってから更新を行う。その間、他の更新処理は自分の処理が完了するまで待ち状態となる。<br />
一方、楽観的ロックであれば、自分がデータ取得後に他人がデータを更新できてしまう。自分がその後に更新しようとすると JPA 利用時、 OptimisticLockException が発生する。<br />

<h3>概要</h3>

JPA(Java Persistence API) 1.0では楽観的ロックのみサポートしている。2.0 からは悲観的ロックもサポートするらしい。<br />
<br />
Seasar2 + Hibernate + JPA 1.0 の構成において悲観的ロックでデータを更新したいと思い試行錯誤したが、意外とつまづいた。<br />
EntityManager に lock() というメソッドがあって、write lock もできそうだが、うまくいかない。seasar がサポートしていないのか、設定がうまくいっていないのか...<br />
<br />
結局、以下の方法で実現できた。

<h3>悲観的ロックによる更新方法</h3>

次のようなコードになる。

<pre name="code" class="java">
package jp.trasis.sample.service;

import javax.persistence.EntityManager;

import jp.trasis.sample.entity.User;

import org.seasar.extension.tx.annotation.RequiresNewTx;
import org.seasar.framework.container.annotation.tiger.Binding;

public class TestService {
	@Binding
	private EntityManager entityManager;
	
	@RequiresNewTx
	public void test(Long userId, String name) {
		User user = (User) entityManager.createNativeQuery(
				"select * from User_ where id=:userId for update", User.class)
			.setParameter("userId", userId)
			.getSingleResult();
		
		user.setName(name);

		entityManager.persist(user);
	}
}
</pre>

<h4>解説</h4>

@RequiresNewTx アノテーションにより、新たなトランザクションの中で更新処理を行う。<br />
<br />
まず、更新対象のエンティティを <b>select ... for update</b> により、行ロックを行いながら取得する。<br />
この SQL は createNativeQuery() メソッドで実行する必要がある。crateQuery() で使用する HQL では、 for update 文は利用できない。<br />
<br />
そしてエンティティに対して修正を行い、 persist() でコミットを行う。メソッドを抜けるときに実際に DB へのコミット処理が行われ、トランザクションが終了し、ロックも開放される。]]>
        
    </content>
</entry>

<entry>
    <title>Eclipseで.jsファイルに日本語文字を使うと文字化けする問題の回避方法</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2009/04/eclipseでjsファイルに日.html" />
    <id>tag:trasis.jp,2009:/blog/lab//2.96</id>

    <published>2009-04-07T11:56:01Z</published>
    <updated>2009-04-08T01:10:56Z</updated>

    <summary>概要 Eclispe 上で JavaScript(.js) ファイルに日本語を使...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="Java" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="eclipse" label="eclipse" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>概要</h3>

Eclispe 上で JavaScript(.js) ファイルに日本語を使うと、保存できなかったり、再度開くと文字化けしたりする。<br />
<a href="http://tockri.blog78.fc2.com/blog-entry-76.html" ref="nofollow">こちらのブログ記事</a> に、その対策方法が記載されている。<br />
<br />
このブログによると、Eclipse に次の設定を行うことで解決できる。

<h3>動作確認環境</h3>

<table class="mytable">
<tr><th>項目</th><th>内容</th></tr>
<tr><td>Eclipse バージョン</td><td>3.3.2<br />3.4.1</td></tr>
</table>

<h3>設定手順</h3>

エクスプローラで、次のファイルを編集する。
<pre class="code2">
workspace\.metadata\.plugins\org.eclipse.core.runtime\.settings\org.eclipse.core.runtime.prefs
</pre>

<br />
次の内容を記述して Eclipse を再起動。
<pre class="code2">
content-types/org.eclipse.wst.javascript.core.javascriptsource/charset=
</pre>

<h3>プロジェクトごとに設定できるか？</h3>

複数人で開発しているときは、全員にこの設定をしてもらわないといけないし、Eclipse を新たなPCにインストールしたときも、この設定を行わないといけないので面倒...<br />
<br />
ということで、プロジェクトにこの設定を行うことができるかどうかを試した。<br />
結論は、残念ながら<b>できない</b>。<br />
<br />
プロジェクト直下にある .setting フォルダに org.eclipse.core.runtime.prefs ファイルを作成し、上記の記述を行ってみたが、反映されなかった。<br />
<br />
<a href="http://mergedoc.sourceforge.jp/">Eclipse Pleiades All-in-one</a> で対応してくれたらいいな...<br />
]]>
        
    </content>
</entry>

<entry>
    <title>PostgreSQLで現在実行中のSQLの確認と、プロセスのkill</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2009/04/postgresqlで現在実行中.html" />
    <id>tag:trasis.jp,2009:/blog/lab//2.95</id>

    <published>2009-04-07T11:40:18Z</published>
    <updated>2009-04-07T12:09:37Z</updated>

    <summary>概要 PostgreSQL上で実行中のSQLを停止する方法について説明する。 J...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="PostgreSQL" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>概要</h3>

PostgreSQL上で実行中のSQLを停止する方法について説明する。<br />
<br />
Javaサーバ上で時間のかかるSQLを実行してしまい、Javaサーバを停止せずにそのスレッドだけを停止したい場合などにおいて、次の手順で実行された SQL を停止できる。<br />

<h3>手順</h3>

<h4>プロセスID(pid)の確認</h4>

まず、問題のSQLが実行されるプロセスのIDを調べる。<br />
コマンドラインなどで、次のSQLを実行。

<pre class="code2">
SELECT
    procpid,
    start,
    now() - start AS lap,
    current_query
FROM
    (SELECT
        backendid,
        pg_stat_get_backend_pid(S.backendid) AS procpid,
        pg_stat_get_backend_activity_start(S.backendid) AS start,
        pg_stat_get_backend_activity(S.backendid) AS current_query
    FROM
        (SELECT pg_stat_get_backend_idset() AS backendid) AS S
    ) AS S
WHERE
    current_query <> '<IDLE>'
ORDER BY
    lap DESC;
</pre>

それぞれの項目は次の意味を表す。

<table class="mytable">
<tbody>
<tr><th>procpid</th><td>プロセスID</td></tr>
<tr><th>start</th><td>プロセス実行開始時間</td></tr>
<tr><th>lap</th><td>経過時間</td></tr>
<tr><th>current_query</th><td>実行中のSQL</td></tr>
</tbody>
</table>

<h4>プロセスの停止</h4>

プロセスIDが分かったら、次のSQLでプロセスを停止できる。<br />

<pre class="code2">
SELECT pg_cancel_backend(<font color="red">プロセスID</font>);
</pre>

<h3>参考URL</h3>

<a href="http://knocking.g.hatena.ne.jp/elf/20071113/1194928670" ref="nofllow">PostgreSQLで実行中のSQLの情報を取得する @ ELFの業務日誌</a><br />
]]>
        
    </content>
</entry>

<entry>
    <title>Log4JのDTD</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2008/11/log4jのdtd.html" />
    <id>tag:trasis.jp,2008:/blog/lab//2.93</id>

    <published>2008-11-18T07:58:35Z</published>
    <updated>2008-11-18T15:21:08Z</updated>

    <summary>概要 Log4J の設定ファイルを log4j.properties ではなく ...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="Java" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>概要</h3>

Log4J の設定ファイルを log4j.properties ではなく log4j.xml で記述する際、Eclipse で編集中、文法をチェックしてもらえたら便利だ。<br />
<br />
Log4J の DTD は jar ファイル(例:  log4j-1.2.14.jar) の中のorg.apache.log4j.xml の中に log4j.dtd の名前で存在している。<br />
が、わざわざ Eclipse にこの DTD を登録したり、Log4J に新しい構文が追加されたときに設定しなおすのでは不便。<br />

<br />
本家の web サイト上で log4j.dtd を公開してくれるのが最も良い解決法だと思うが、探しても見つからない。

<h3>解決法</h3>

log4j.xml で、次のように DOCTYPE を記述する。<br />

<textarea name="code" class="xml">
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration PUBLIC "-//Apache Software Foundation//DTD Log4J Configuration 1.0//EN"
	"http://renga.googlecode.com/svn-history/r4/vendor/logging-log4j-1.2.14/docs/api/org/apache/log4j/xml/log4j.dtd">
<log4j:configuration>
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p %d [%t] %c: %m%n" />
		</layout>
 	</appender>

	<root>
		<level value="INFO" />
		<appender-ref ref="console" />
	</root>
</log4j:configuration>
</textarea>
]]>
        
    </content>
</entry>

<entry>
    <title>Windows Updateできない問題を解決</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2008/11/windows-updateできない問.html" />
    <id>tag:trasis.jp,2008:/blog/lab//2.92</id>

    <published>2008-11-06T07:54:21Z</published>
    <updated>2008-11-09T04:20:08Z</updated>

    <summary>現象 OSなしのマシンに Windows XP Pro をインストールしたところ...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>現象</h3>

OSなしのマシンに Windows XP Pro をインストールしたところ、Windows Update ができない。<br />
<br />
C:\Windows\WindowsUpdate.log を見ると、ファイルの最後へ次のように記録されている。
<pre class="code2">
COMAPI	WARNING: Operation failed due to earlier error, hr=80004002
</pre>

<h3>解決方法</h3>

<a href="http://d.hatena.ne.jp/Gazebo/20070802/p1">こちら</a> を参考に解決。<br />
<br />
DOS プロンプトを起動し、次のコマンドをカット＆ペーストで貼り付け、実行する。
<pre class="code2">
%Windir%\system32\net.exe stop bits
%Windir%\system32\net.exe stop wuauserv  
%Windir%\system32\regsvr32.exe %Windir%\system32\atl.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\jscript.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\msxml3.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\softpub.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wuapi.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wuaueng.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wuaueng1.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wucltui.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wups.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wups2.dll
%Windir%\system32\regsvr32.exe %Windir%\system32\wuweb.dll
%Windir%\system32\net.exe start bits
%Windir%\system32\net.exe start wuauserv
</pre>
]]>
        
    </content>
</entry>

<entry>
    <title>tomcat セッション(PersistentManager, StandardSession)のデバッグ</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2008/11/tomcat-セッションのデバッグ.html" />
    <id>tag:trasis.jp,2008:/blog/lab//2.91</id>

    <published>2008-11-02T05:38:41Z</published>
    <updated>2008-11-02T06:00:22Z</updated>

    <summary>概要 web アプリケーションの負荷試験などを行う際、tomcat のセッション...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="tomcat" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>概要</h3>

web アプリケーションの負荷試験などを行う際、tomcat のセッションの入出力状態をモニターしたくなることがある。<br />
<br />
また、Hibernate + Seasar + Wicket でアプリケーション構築時、セッションのデシリアライズがうまくいかないことがあり、tomcat の PersistentManager や StandardSession の動作を追っていくことで問題を発見、修正できることがある。<br />

<h3>Linux で tomcat 動作時のデバッグ手順</h3>

logging.properties を次のように修正する。
<pre class="code2">
handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler

<font color="red"><b>1catalina.org.apache.juli.FileHandler.level = FINEST</b></font>
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.prefix = catalina.

java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

<font color="red"><b>
#org.apache.catalina.level = INFO
org.apache.catalina.level = FINEST

org.apache.catalina.connector.level = INFO
org.apache.catalina.loader.level = INFO
org.apache.catalina.startup.level = INFO
org.apache.catalina.mbeans.level = INFO
</b></font>
</pre>

これで、catalina.out に詳細なログが出力される。

<h3>Eclipse + WTP + tomcat 環境でのデバッグ方法</h3>

Eclipse 上で次の操作を行う。
<ul>
<li> [実行] メニュー ⇒ [実行ダイアログを開く]</li>
<li> ダイアログ左側の一番上にある「Apache Tomcat」の中の、「localhost の tomcat v6.0 サーバー」をクリック。</li>
<li> ダイアログ右側から「引数」タブを開く。</li>
<li> VM引数に次のような記述を追加する。パスは自分の環境に合わせて適宜修正する。
<div class="code2">
-Djava.util.logging.config.file="C:\usr\apache-tomcat-6.0.16\conf\my.logging.properties" 
</div></li>
</ul>
<br />
次に、c:\usr\apache-tomcat-6.0.16\conf\my.logging.properties ファイルを作成する。
<pre class="code2">
handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
.handlers = 1catalina.org.apache.juli.FileHandler, java.util.logging.ConsoleHandler

<font color="red"><b>1catalina.org.apache.juli.FileHandler.level = FINEST</b></font>
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.prefix = catalina.

java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

<font color="red"><b>
#org.apache.catalina.level = INFO
org.apache.catalina.level = FINEST

org.apache.catalina.connector.level = INFO
org.apache.catalina.loader.level = INFO
org.apache.catalina.startup.level = INFO
org.apache.catalina.mbeans.level = INFO
</b></font>
</pre>

これで tomcat 起動時、catalina.out に詳細なログが出力されるようになる。<br />
<br />
ちなみに、catalina.out の場所は workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\logs となる(Eclipse 3.3.2 Preiades All in One の場合)。]]>
        
    </content>
</entry>

<entry>
    <title>Maven+Spring+Hibernate+JPA+JUnit4環境構築</title>
    <link rel="alternate" type="text/html" href="http://trasis.jp/blog/lab/2008/09/maven-spring-hibernate-jpa-junit4.html" />
    <id>tag:trasis.jp,2008:/blog/lab//2.90</id>

    <published>2008-09-12T17:54:03Z</published>
    <updated>2008-11-16T14:15:02Z</updated>

    <summary>概要 今回は Maven + Spring Framework + Hibern...</summary>
    <author>
        <name>馬原賢吉</name>
        
    </author>
    
        <category term="Java" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="hibernate" label="hibernate" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="jpa" label="jpa" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="junit" label="junit" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="maven" label="maven" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="spring" label="spring" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://trasis.jp/blog/lab/">
        <![CDATA[<h3>概要</h3>

今回は Maven + Spring Framework + Hibernate + JPA + JUnit の組み合わせで環境構築。<br />

<h4>開発環境</h4>

<table class="mytable">
<tbody><tr>
	<th>項目</th><th>値</th>
</tr>
<tr>
	<td>OS</td>
	<td>Windows XP Pro SP2</td>

</tr>
<tr>
	<td>IDE 環境</td>
	<td><a href="http://mergedoc.sourceforge.jp/index.html#/pleiades_distros3.3.html">Eclipse 3.3.2(Preiades All in One)</a></td>
</tr>
<tr>
	<td>Java</td>
	<td><a href="http://java.sun.com/javase/ja/6/download.html">JDK 6 update 6</a></td>
</tr>

<tr>
	<td>DB</td>
	<td><a href="http://www.postgresql.jp/PostgreSQL">PostgreSQL 8.3</a></td>
</tr>
</tbody></table>

<h3>準備</h3>

次の手順まで<a href="/blog/lab/2008/09/hibernate-jpa環境構築.html">Hibernateを使ったシンプルなJPA環境構築</a>と同じように進める。<br />
<ul>
	<li> Maven プロジェクト作成</li>
	<li> Java コンパイラー準拠レベルの設定</li>
	<li> pom.xml を設定する</li>
	<li> 設定ファイル作成
	<ul>
		<li> META-INF/persistence.xml</li>
		<li> ehcache.xml</li>
		<li> log4j.properties</li>
	</ul></li>
	<li> BaseEntity, User クラス作成</li>
</ul>

<h3>pom.xml 修正</h3>

次のように修正する。

<textarea class="code2" style="height: 40em">
<?xml version="1.0" encoding="UTF-8"?>
<project>
	<modelVersion>4.0.0</modelVersion>
	<groupId>trasis-sample</groupId>
	<artifactId>jpa1</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<dependencies>
		<dependency>
			<groupId>postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<version>8.3-603.jdbc4</version>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.4</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring</artifactId>
			<version>2.5.5</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>3.3.2.GA</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.14</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>
			<groupId>aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.5.4</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>2.5.5</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.4</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>
</textarea>

<h3>src/main/resources ソース・フォルダ</h3>

<h4>META-INF/persistence.xml</h4>

次のように修正する。

<textarea class="code2" style="height: 20em">
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
	version="1.0">

	<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>

		<jar-file>.</jar-file>
		<exclude-unlisted-classes>false</exclude-unlisted-classes>

		<properties>
			<property name="hibernate.cache.provider_class"	value="org.hibernate.cache.EhCacheProvider" />
			<property name="hibernate.cache.provider_configuration_file_resource_path" value="/ehcache.xml" />
			<property name="hibernate.cache.use_query_cache"		value="true" />
			<property name="hibernate.cache.use_second_level_cache"	value="true" />

			<!-- none | update | create-drop -->
			<property name="hibernate.hbm2ddl.auto"		value="update" />

			<property name="hibernate.show_sql"			value="false" />
			<property name="hibernate.format_sql"		value="true" />
			<property name="hibernate.use_sql_comments" value="false" />

			<property name="hibernate.max_fetch_depth" value="3" />
			<property name="hibernate.jdbc.batch_size" value="100" />

		</properties>
	</persistence-unit>
</persistence>
</textarea>

Maven を使う場合、エンティティクラスは src/main/java に、META-INF/persistence.xml ファイルなどは src/main/resources フォルダに置く。<br />
この環境で Spring Framework + Hibernate にうまくクラスのアノテーションをスキャンしてもらうために、次のように記述している。
<textarea class="code2">
<jar-file>.</jar-file>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
</textarea>

<h4>applicationContext.xml</h4>

Spring Framework の設定。<br />

<textarea class="code2" style="height: 40em">
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
    	http://www.springframework.org/schema/beans		http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
		http://www.springframework.org/schema/aop		http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
		http://www.springframework.org/schema/tx		http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
		http://www.springframework.org/schema/context	http://www.springframework.org/schema/context/spring-context-2.5.xsd">

	<context:property-placeholder location="classpath:jdbc.properties" />

	<!-- アノテーション検索パッケージ  -->
	<context:component-scan base-package="test.test" />

	<bean id="dataSource"
		class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>

	<bean id="entityManagerFactory"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

		<property name="dataSource" ref="dataSource" />
		<property name="jpaVendorAdapter">
			<bean
				class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="showSql" value="true" />
				<property name="generateDdl" value="false" />
			</bean>
		</property>
	</bean>

	<bean id="transactionManager"
		class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory"
			ref="entityManagerFactory" />
	</bean>

	<context:annotation-config />

	<!-- @Transactional: トランザクション自動開始 -->
	<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
</textarea>

Spring Framework 2.5 からサポートされたいくつかの記述により、前のバージョンよりも記述が簡単になっている。<br />

<br />
<b>context:property-placeholder</b> によって、jdbc.properties を読み込んでいる。<br />
${jdbc.url} のように applicationContext.xml 内に記述すると置換される。<br />

<br />
<b>context:annotation-config</b> によって、クラスをスキャンし、@Service などのアノテーションを解釈する。<br />
<b>&lt;context:component-scan base-package="test.test" /&gt;</b> によってスキャンするパッケージを明示的に指定している。<br />

<br />
<b>tx:annotation-driven</b> によって、@Transactional アノテーションを解釈する。<br />


<h4>jdbc.properties</h4>

新たに作成。applicationContext.xml の中で ${jdbc.driverClassName} などが置換される。

<textarea class="code2" style="height: 5em">
jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/sandbox
jdbc.username=postgres
jdbc.password=postgres
</textarea>

<h3>Dao 作成</h3>

src/main/java フォルダの中で test.test.dao.UserDao クラスを作成する。

<textarea class="code2" style="height: 40em">
package test.test.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import test.test.entity.User;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class UserDao {
	@PersistenceContext
	private EntityManager entityManager;

	public void persist(User user) {
		entityManager.persist(user);
	}

	public void remove(User user) {
		entityManager.remove(user);
	}

	public void remove(Long id) {
		entityManager.createQuery("delete from Users c where id=?1")
			.setParameter(1, id)
			.executeUpdate();
	}

	public User find(Long id) {
		return entityManager.find(User.class, id);
	}

	public User findByMailAddress(String mailAddress) {
		return (User) entityManager
			.createQuery("from Users c where mailAddress=?1")
			.setParameter(1, mailAddress)
			.getSingleResult();
	}

	@SuppressWarnings("unchecked")
	public List<User> findAll() {
		return entityManager.createQuery("from Users").getResultList();
	}
}
</textarea>

<br />
<b>@Service</b> アノテーションを指定すると、Spring Framework のビーンとして解釈され、他のビーンから @Resource アノテーションなどによって呼び出せる。<br />

<br />
<b>@Transactional</b> アノテーションによって、このクラスのメソッド呼び出し時に、トランザクションがまだオープンされていなければ、自動的にオープンする。<br />

<h3>JUnit4 によるテスト</h3>

<h4>テストケースの作成</h4>

src/test/java フォルダの中で test.test.DBTest を作成する。

<textarea class="code2" style="height: 40em">
package test.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.util.List;

import javax.annotation.Resource;
import javax.persistence.NoResultException;

import test.test.dao.UserDao;
import test.test.entity.User;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext.xml"})
@Transactional
public class DBTest {
	private static final String MAIL_ADDRESS = "test3@example.com";

	@Resource
	private UserDao userDao;

	@Test
	public void test1() throws InterruptedException {
		// 追加
		{
			User user = new User();
			user.setMailAddress(MAIL_ADDRESS);
			user.setPassword("test");
			userDao.persist(user);
		}

		// 検索1
		{
			List<User> list = userDao.findAll();
			assertEquals(1, list.size());

			User user = list.get(0);
			assertEquals(MAIL_ADDRESS, user.getMailAddress());
			assertEquals("test", user.getPassword());
		}

		// 検索2
		User user = userDao.findByMailAddress(MAIL_ADDRESS);
		assertEquals(MAIL_ADDRESS, user.getMailAddress());
		assertEquals("test", user.getPassword());

		// 削除
		userDao.remove(user);

		try {
			user = userDao.findByMailAddress(MAIL_ADDRESS);
			fail();
		} catch (NoResultException e) {
			// ok
		}
	}
}
</txetarea>

<br />
<b>@RunWith(SpringJUnit4ClassRunner.class)</b> アノテーションによって、@Transactional によってトランザクションをオープンしたり、@Resource によってビーンの注入を行った状態でテストを実行することが可能になる。<br />

<br />
なお、テストを実行しても、トランザクションはデフォルトでは自動的にロールバックされる。<br />
テストの結果、コミットされるようにするには、test1() メソッドに対して @Rollback(false) を宣言する。


<h4>テストスイートの作成</h4>

複数のテストケースを実行するテストスイート test.test.AllTests を作成する。<br />

<textarea class="code2" style="height: 40em">
package test.test;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({
 		DBTest.class
})
public class AllTests {
}
</textarea>
]]>
        
    </content>
</entry>

</feed>
