@ResourceアノテーションでDataSourceを注入してみる
TweetPosted on Sunday Feb 02, 2014 at 05:23PM in Technology
直接JDBCを使う必要がでてきた時用。
環境
- WildFly8.0.0.CR1
- Oracle JDK7u51
- PostgreSQL 9.2.4
準備
データソースを確認
こんなデータソースを使ってみることにする
[standalone@localhost:9990 /] /subsystem=datasources/data-source=TestDS:read-attribute(name=jndi-name)
{
"outcome" => "success",
"result" => "java:jboss/jdbc/TestDS"
}
[standalone@localhost:9990 /]
HogeServlet.java
このサーブレットにDataSourceを注入します。try-with-resourcesが便利ですね。@Resourceアノテーションのlookup属性には、“java:comp/env/“の後にXMLファイルで定義した論理名を書く
package com.example;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
@WebServlet("/HogeServlet")
public class HogeServlet extends HttpServlet {
@Resource(lookup = "java:comp/env/jdbc/hoge")
DataSource dataSource;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try(PrintWriter pw = response.getWriter();
Connection cn = dataSource.getConnection();
Statement st = cn.createStatement();
ResultSet rs = st.executeQuery("select now()")){
while(rs.next()){
pw.write(String.valueOf(rs.getTimestamp(1)));
}
}catch(SQLException e){
throw new ServletException(e);
}
}
}
web.xml
この環境の場合はなくても動くようだが一応。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<resource-ref>
<res-ref-name>jdbc/hoge</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
</resource-ref>
</web-app>
jboss-web.xml
WEB-INFの下に置く。ここでデータソースのJNDI名とResourceアノテーションのlookup属性で指定した名前のひも付けを行う。
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<resource-ref>
<res-ref-name>jdbc/hoge</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<jndi-name>java:jboss/jdbc/TestDS</jndi-name>
</resource-ref>
</jboss-web>
動かしてみる

テストの際はどうするか
jboss-web.xmlを別のものに差し替えればOK。HogeServletには手を入れずに参照するDBを切り替えることができる。
備考
JPAのpersistence.xmlからはweb.xmlとjboss-web.xmlで定義した論理名を参照できない
persistence.xmlからもweb.xmlとjboss-web.xmlで定義した論理名 “jdbc/hoge” を使う事が出来れば、jboss-web.xmlを差し替えるだけでJPAから参照するデータソースも切り替えられるので楽だなと思ったのだが、どうやらそれは出来ないらしい[2]。“java:comp/env/jdbc/hoge” とかも試してみたが駄目だった。persistence.xmlにはAPサーバに定義してあるJNDI名を直接指定してやる必要があるみたい。残念。WebSphereだとできたりするみたいだけど一般的には駄目っぽい[5]。
今回の例だとこう書いてやる必要がある。
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="datasource">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/jdbc/TestDS</jta-data-source>
</persistence-unit>
</persistence>
ただアプリケーションローカルでweb.xmlかアノテーションで定義したデータソースを使う場合は共用が可能らしい[3]。アプリの資源に接続情報べた書きになるので避けたい気もするが用途によっては良いのかもしれない。
@Resourceで直接JNDI名を参照する
特に論理名を通じて利用する必要がないなら、HogeServlet.javaで以下のようにすれば直接JNDI名からデータソースを拾って来れる。jboss-web.xmlもweb.xmlも不要になる。
ただし複数箇所でJNDI名の直書きが発生するのはあまりよろしくないので、CDIのProducerを使うか、前述の手段で論理名を通して参照した方が良いような気はする。
package com.example;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
@WebServlet("/HogeServlet")
public class HogeServlet extends HttpServlet {
@Resource(lookup="java:jboss/jdbc/TestDS")
DataSource dataSource;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try(PrintWriter pw = response.getWriter();
Connection cn = dataSource.getConnection();
Statement st = cn.createStatement();
ResultSet rs = st.executeQuery("select now()")){
while(rs.next()){
pw.write(String.valueOf(rs.getTimestamp(1)));
}
}catch(SQLException e){
throw new ServletException(e);
}
}
}
参考文献
Tags: wildfly
ログ出力の設定をしてみる
TweetPosted on Sunday Feb 02, 2014 at 10:43AM in Technology
環境
- PostgreSQL 9.2.4
- OS X 10.9.1
何をするか
- OS XのsyslogをPostgreSQLからのログ出力を受け入れられるように設定する
- PostgreSQLのログをsyslogへ出力するようにする
- 実行されるSQLのログを取ってみる
OS Xのsyslogの設定
/etc/syslog.confを編集する
一番下の行を追加する。こんな感じ。flat file logsは/etc/asl.confに設定されているとか書かれているのでそっちに書いた方がいいのかもしれないけど面倒なのでここで
# Note that flat file logs are now configured in /etc/asl.conf install.* @127.0.0.1:32376 local0.* /var/log/postgresql
設定内容を反映させる
sudo launchctl unload /System/Library/LaunchDaemons/com.apple.syslogd.plist sudo launchctl load /System/Library/LaunchDaemons/com.apple.syslogd.plist
こんなんでもよい
ps -Af | awk '/\/usr\/sbin\/syslogd$/{print "sudo kill -HUP " $2}' | sh
ログを出力してみる
kyle-no-MacBook:etc kyle$ logger -p local0.notice hogehoge kyle-no-MacBook:etc kyle$ ls -l /var/log/postgresql -rw-r--r--@ 1 root wheel 58 2 2 10:55 /var/log/postgresql kyle-no-MacBook:etc kyle$ cat /var/log/postgresql Feb 2 10:55:06 kyle-no-MacBook.local kyle[880]: hogehoge kyle-no-MacBook:etc kyle$
ちゃんと出ていますね。「コンソール」からも内容を見られるのは便利かも

PostgreSQLの設定
$PG_HOME/data/postgresql.confを編集
sudo su postgres -c 'vi /Library/PostgreSQL/9.2/data/postgresql.conf'
以下内容にする
log_destination = 'syslog' syslog_facility = 'LOCAL0' syslog_ident = 'postgres' log_statement = 'all'
一番下がSQLをログに出す設定。大量に出るので要注意
再起動
sudo su postgres -c 'pg_ctl -D /Library/PostgreSQL/9.2/data restart'
ログを見てみる
kyle-no-MacBook:~ kyle$ psql
Password:
psql (9.2.4)
Type "help" for help.
kyle=# select now();
now
------------------------------
2014-02-02 11:32:20.67332+09
(1 row)
kyle=# \q
kyle-no-MacBook:~ kyle$ cat /var/log/postgresql.log
Feb 2 11:20:21 kyle-no-MacBook.local kyle[1002]: hogehogehoge
Feb 2 11:31:24 kyle-no-MacBook.local postgres[1073]: [1-1] 2014-02-02 11:31:24 JST LOG: database system was shut down at 2014-02-02 11:31:23 JST
Feb 2 11:31:24 kyle-no-MacBook.local postgres[1077]: [1-1] 2014-02-02 11:31:24 JST LOG: autovacuum launcher started
Feb 2 11:31:24 kyle-no-MacBook.local postgres[1071]: [1-1] 2014-02-02 11:31:24 JST LOG: database system is ready to accept connections
Feb 2 11:31:30 kyle-no-MacBook.local postgres[1083]: [2-1] 2014-02-02 11:31:30 JST LOG: incomplete startup packet
Feb 2 11:32:20 kyle-no-MacBook.local postgres[1098]: [2-1] 2014-02-02 11:32:20 JST LOG: statement: select now();
kyle-no-MacBook:~ kyle$
出てますね
その他
できればSQLのログはシビリティをdebugとかにしたいので若干調べた[6]が、よくわからん。現状無理ということだろうか
参考文献
- Linux管理者への道(3):システム管理の基礎 syslogdの設定をマスターしよう (2/3) - @IT
- ログ関連の設定 — Let's Postgres
- 第10回Mac OS X Server勉強会 Mac OSXシステム管理 読書会「ログ」 - サイト更新停滞ちうっ
- 新世代syslogデーモン徹底活用(1):syslogdの限界と次世代シスログデーモン (1/3) - @IT
- PostgreSQL/PostgreSQLでSQLステートメントをログファイルに出力する方法 - 調べる.db
- [GENERAL] log_statement and syslog severity - Google グループ
Tags: postgres
