Dec 26, 2008

[AS] Tomcat Native で不可思議なエラー

Apache HTTP Server + APR + Tomcat Native + Apache Tomcat 環境下で、特定条件の HTTP コネクションが途中で切れる現象が発生した。 結論から言うと Tomcat Native のバグの様で、Tomcat Native をバージョンアップしたら直った。 同様の症状が発生したという情報は見つかったが、解決したという情報が見当たらなかったのでメモ。

症状が発生した環境

  • Apache HTTP Server 2.2.6
  • Apache Portable Runtime 1.2.7-10
  • Apache Tomcat 5.5.25
  • Apache Tomcat Native 1.1.6

出力されたログ

/var/log/httpd/error_log

[error] (70014)End of file found: ajp_ilink_receive() can't receive header
[error] ajp_read_header: ajp_ilink_receive failed
[error] (120006)APR does not understand this error code: proxy: dialog to 127.0.0.1:8009 (localhost) failed

$CATALINA_HOME/logs/catalina.out

ClientAbortException:  java.io.IOException
        at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:366)
        at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:432)
        at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:291)
        at org.apache.catalina.connector.OutputBuffer.writeByte(OutputBuffer.java:414)
        at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:77)
        at java.io.FilterOutputStream.write(FilterOutputStream.java:60)
        at java.io.FilterOutputStream.write(FilterOutputStream.java:108)

    (SNIP)

        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
        at org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:444)
        at org.apache.coyote.ajp.AjpAprProtocol$AjpConnectionHandler.process(AjpAprProtocol.java:472)
        at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1286)
        at java.lang.Thread.run(Thread.java:595)
Caused by: java.io.IOException
        at org.apache.coyote.ajp.AjpAprProcessor.flush(AjpAprProcessor.java:1199)
        at org.apache.coyote.ajp.AjpAprProcessor$SocketOutputBuffer.doWrite(AjpAprProcessor.java:1284)
        at org.apache.coyote.Response.doWrite(Response.java:560)
        at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:361)
        ... 26 more

解決策

Tomcat Native を 1.1.6 → 1.1.8 にバージョンアップしたら改善した。

Posted in AS | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Nov 08, 2008

[Tiger] Java SE のサポート終了ポリシーをメモ

2008/10/30 を以て Java SE 1.4 が EOSL を迎えた。 1 年後の 2009/10/30 には Java SE 5.0 までもが EOSL を迎える。 Java SE for Business も考慮しなくてはいけないかもしれない。

Java SE & Java SE for Business Support Road Map
http://java.sun.com/products/archive/eol.policy.html
Sun End of Service Life (EOSL) Policy
http://www.sun.com/service/eosl/index.jsp
Java SE for Business
http://www.sun.com/software/javaseforbusiness/
Java SE for Business(日本語)
http://jp.sun.com/products/software/javaseforbusiness/index.html

Posted in Tiger | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Nov 07, 2008

[AS] Apache Tomcat + DBCP で Connection のリークを確認する方法をメモ

Apache Tomcat + DBCP の環境で Connection のリークを確認する方法をメモしておく。 この設定のおかげで、リリース直前のコードに潜んでいた Connection のリークを発見できた。 Connection を自前でハンドリングするのであれば、もう少し気を使ってコーディングして欲しいものだ。 とは言え、コーディングするのも人間。 ミスすることを前提として、開発環境では必ずこの設定をしておきたい。 そのうち自分でやらかして怒られるかもしれないし(^^;

Apache Tomcat 6.0 - JNDI Datasource HOW-TO : Preventing dB connection pool leaks
http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html#Preventing%20dB%20connection%20pool%20leaks

context.xml の設定

Apache Tomcat にディプロイする Web アプリケーションの context.xml に以下の設定を追加する。

<Context ...>
  <Resource ...
        factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"
        removeAbandoned="true"
        removeAbandonedTimeout="300"
        logAbandoned="true" />
</Context>

各設定の意味は以下の通り(Commons DBCP - Configurationより抜粋)。
Parameter Default Description
removeAbandoned false Flag to remove abandoned connections if they exceed the removeAbandonedTimout. If set to true a connection is considered abandoned and eligible for removal if it has been idle longer than the removeAbandonedTimeout. Setting this to true can recover db connections from poorly written applications which fail to close a connection.
removeAbandonedTimeout 300 Timeout in seconds before an abandoned connection can be removed.
logAbandoned false Flag to log stack traces for application code which abandoned a Statement or Connection. Logging of abandoned Statements and Connections adds overhead for every Connection open or new Statement because a stack trace has to be generated.

設定の確認

設定が有効な状態で Apache Tomcat を起動すると、起動時に下記の様なメッセージがコンソールに出力される。

AbandonedObjectPool is used (org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool@5f8bae)
   LogAbandoned: true
   RemoveAbandoned: true
   RemoveAbandonedTimeout: 300

コネクションのリーク検知

コネクションのリークが検知されると、以下の様なログが出力される。

DBCP object created 2008-11-06 12:01:25 by the following code was never closed:
java.lang.Exception
  at org.apache.tomcat.dbcp.dbcp.AbandonedTrace.setStackTrace(AbandonedTrace.java:157)
  at org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:76)
  at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95)
  at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:540)
  at jp.in_vitro.myapp.MyServlet.doGet(MyServlet.java:10)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
  at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:833)
  at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:639)
  at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1285)
  at java.lang.Thread.run(Thread.java:595)

Posted in AS | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Nov 05, 2008

Oct 30, 2008

[Linux] apt-get で Debian Unofficial からパッケージを取得する

"apt-cache search" で欲しいパッケージが見つからない。 そんなときに重宝するのが Debian Unofficial だそうだ。 Debian Unofficial では公式サイトにはないパッケージを多数用意してくれているということで "make" が面倒なものぐさ人間には非常に有り難い。

Debian Unofficial is a repository for packages not available within the official Debian repository. It contains packages which are not distributable within Debian due to special license terms as well as packages which are not included in Debian due to political reasons (e.g. alleged possible patent infrigement, binary-only/no sources, or special too restrictive licenses).
Debian Unofficial
http://www.debian-unofficial.org/

Debian Unofficial の設定

/etc/apt/sources.list に以下を追記する。

deb http://ftp.debian-unofficial.org/debian etch main contrib non-free restricted
deb-src http://ftp.debian-unofficial.org/debian etch main contrib non-free restricted

"GPG error" の対処

上記設定を行い、"apt-get update" を行うと、下記の様なエラーが出る。

# apt-get update
    (略)
Fetched 7605kB in 6s (1167kB/s)
Reading package lists... Done
W: GPG error: http://ftp.debian-unofficial.org etch Release: The following signatures
couldn't be verified because the public key is not available: NO_PUBKEY 394D199524C52AC3
W: You may want to run apt-get update to correct these problems
#
このエラーの対処方法は Debian Unofficial の FAQ に記載されている。
Debian Unofficial - 5. Frequently Asked Questions (FAQ)
http://www.debian-unofficial.org/faq.html
・・・が、この FAQ の通りに実行しても直らなかった。 エラーが直った対処方法は以下の通り。

まず、エラーメッセージにある PUBKEY から gpg コマンドを使用してキーを取得する。

# gpg --keyserver subkeys.pgp.net --recv-keys 394D199524C52AC3
gpg: requesting key 24C52AC3 from hkp server subkeys.pgp.net
gpg: key 24C52AC3: public key "Debian Unofficial Archive Automatic Signing Key (2007) " imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1
#
次に取得したキーを apt に登録する。
# gpg --armor --export 394D199524C52AC3 | apt-key add -
OK
#
これで OK。
# apt-get update
    (略)
Ign http://ftp.debian-unofficial.org etch/main Sources/DiffIndex
Ign http://ftp.debian-unofficial.org etch/contrib Sources/DiffIndex
Ign http://ftp.debian-unofficial.org etch/non-free Sources/DiffIndex
Ign http://ftp.debian-unofficial.org etch/restricted Sources/DiffIndex
Hit http://ftp.debian-unofficial.org etch/main Packages
Hit http://ftp.debian-unofficial.org etch/contrib Packages
Hit http://ftp.debian-unofficial.org etch/non-free Packages
Hit http://ftp.debian-unofficial.org etch/restricted Packages
Hit http://ftp.debian-unofficial.org etch/main Sources
Hit http://ftp.debian-unofficial.org etch/contrib Sources
Hit http://ftp.debian-unofficial.org etch/non-free Sources
Hit http://ftp.debian-unofficial.org etch/restricted Sources
Fetched 191B in 2s (82B/s)
Reading package lists... Done
#
ちなみに、apt に登録されたキーは以下で確認できる。
# apt-key list
/etc/apt/trusted.gpg
--------------------
    (略)
pub   1024D/24C52AC3 2007-01-24 [expired: 2008-02-01]
uid                  Debian Unofficial Archive Automatic Signing Key (2007) 
#
それにしても、既に失効済みの 2007 年のキーが必要なのは何故だろう? FAQ では 2008 年のキーをインストールする手順が記載されているのに。

Posted in Linux | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 25, 2008

[PostgreSQL] PostgreSQL の varchar, char は文字数か? バイト数か?

という論争が起きたので(笑)、公式のドキュメントで裏を取ってみた。

PostgreSQL : Documentation : Manuals : PostgreSQL 8.2 : Character Types
http://www.postgresql.org/docs/8.2/interactive/datatype-character.html
SQL defines two primary character types: character varying(n) and character(n), where n is a positive integer. Both of these types can store strings up to n characters in length.
ということで、varchar も char も文字数ということの様だ。 ・・・「バイト数でした」ということになっていたら大変なことになるところだった(^^;

Posted in PostgreSQL | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

[Subversion] Subversion の一日分の更新状況をメール通知する

Subversion の一日分の更新情報をメールで送信するシェルスクリプトを載せておく。

#!/bin/sh

REPOS="/my/svn/repos"
TMPFILE="./todayscommit.tmp"
DATE=`date +"%Y-%m-%d"`
DATE2=`date +"%Y/%m/%d"`
SVNLOOK="/usr/bin/svnlook"
YOUNGEST=`$SVNLOOK youngest "$REPOS"`
MAILADDRESS="me@example.com"
MAILSUBJECT="Today's COMMIT $REPOS ($DATE2)"

echo "Today's commit : $DATE2" > $TMPFILE
echo "" >> $TMPFILE

i=$YOUNGEST
while [ $i -ge 0 ];
do
  REVDATE=`$SVNLOOK date -r $i $REPOS | sed -e "s/[[:blank:]].*//g"`
  if [ $REVDATE = $DATE ];
  then
    echo "***** Revision $i ***************************************" >> $TMPFILE
    $SVNLOOK info -r $i $REPOS >> $TMPFILE
  else
    break 1 
  fi
  i=`expr $i - 1`
done

mail -s "$MAILSUBJECT" "$MAILADDRESS" < $TMPFILE

rm $TMPFILE

Posted in Subversion | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 24, 2008

[Misc] Google, Yahoo からサイトを削除する方法

Google, Yahoo からとあるサイトを削除したので、関連ページをメモしておく。 個人情報が漏れた、とかではない。念のため。

Google のインデックスにコンテンツが登録されないようにする、またはインデックスからコンテンツを削除する方法を教えてください。
http://www.google.com/support/webmasters/bin/answer.py?answer=35301
robots.txt ファイルでサイトのアクセスを管理する
http://www.google.com/support/webmasters/bin/answer.py?answer=40360&cbid=-qq8531usfzqy&src=cb&lev=answer
インターネットからウェブページを削除せず、検索結果に表示されないようにする
http://info.search.yahoo.co.jp/archives/002869.php
サイト単位、ディレクトリ単位での巡回の拒否設定 1
http://info.search.yahoo.co.jp/archives/002849.php
検索結果から非表示にするには(インデックス操作)
http://help.yahoo.co.jp/help/jp/siteexplorer/siteexplorer-17.html

サイト側での対応

全検索エンジンに対してクロールを中止し、アーカイブを削除する様にする設定方法。

/robots.txt を作成する。全検索エンジンにサイト全体を disallow する。

User-agent: *
Disallow: /
HTML ヘッダ内にアーカイブ禁止のメタ情報を埋め込む。
<head>
  <meta name="robots" content="noarchive">
</head>

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 23, 2008

[Subversion] Subversion リポジトリの状態をメール通知する

私の環境で使用している Subversion リポジトリの状態をメールで通知するスクリプトを載せておく。 このスクリプトを cron で一週間に一回実行している。

#!/bin/sh

REPOS="/my/svn/repos"
LOCK="$REPOS/access.lock"
DATE=`date +"%Y/%m/%d %H:%M:%S"`
MAILSUBJECT="Today's SVN $REPOS ($DATE)"
MAILADDRESS="me@example.com"

touch $LOCK

SVNADMIN="/usr/bin/svnadmin"
SVNLOOK="/usr/bin/svnlook"
SVNADMIN_LSLOCKS=`$SVNADMIN lslocks $REPOS`
SVNADMIN_LSTXNS=`$SVNADMIN lstxns $REPOS`
SVNADMIN_VERIFY=`$SVNADMIN verify $REPOS 2>&1`
SVNLOOK_YOUNGEST=`$SVNLOOK youngest $REPOS`
REPOSSIZE=`du -s -k $REPOS | sed -e "s/[[:blank:]].*//"`
STORAGE=`df $REPOS`

mail -s "$MAILSUBJECT" "$MAILADDRESS" << EOF
*** Date ***********************************
$DATE

*** Path of Repository *********************
$REPOS

*** Size of Repository *********************
$REPOSSIZE kb

*** Storage ********************************
$STORAGE

*** Youngest revision **********************
$SVNLOOK_YOUNGEST

*** Locks **********************************
$SVNADMIN_LSLOCKS

*** Transactions ***************************
$SVNADMIN_LSTXNS

*** Verify *********************************
$SVNADMIN_VERIFY

EOF

rm $LOCK
スクリプトから届くメールはこんな感じ。
*** Date ***********************************
2008/10/23 00:00:00

*** Path of Repository *********************
/my/svn/repos

*** Size of Repository *********************
2837148 kb

*** Storage ********************************
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/hda1            12537386   6283742 126324102   3% /

*** Youngest revision **********************
3092

*** Locks **********************************


*** Transactions ***************************
2990-1
3024-1
3024-2

*** Verify *********************************
* Verified revision 0.
* Verified revision 1.
* Verified revision 2.

  (略)

* Verified revision 3090.
* Verified revision 3091.
* Verified revision 3092.

Posted in Subversion | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 22, 2008

[Subversion] Subversion リポジトリに対する commit を禁止する方法

Subversion のメンテナンスについて触れたので、 ついでに Subversion リポジトリのメンテナンスを実施する際に必要な commit 禁止の設定方法を書いておく。 Subversion リポジトリへの commit 禁止はリポジトリフックの start-commit を使用すると簡単に実現できる。

Version Control with Subversion - start-commit Repository Hooks
http://svnbook.red-bean.com/en/1.5/svn.ref.reposhooks.start-commit.html

start-commit フックの作成

Subversin リポジトリホーム($REPOS) に hooks というリポジトリフックをを格納する場所が用意されているので、その中に start-commit というファイルを作成する。 テンプレートが用意されているので、それをコピーしてもいい。 作成後は実行権限とアクセス権限を適切なものに変更すること。

$REPOS/hooks/start-commit

#!/bin/sh

REPOS="$1"
USER="$2"

if [ -e "$REPOS/commit.lock" ];
then
  echo "Service temporary unavailable." 1>&2
  exit 1
fi 
exit 0

commit の禁止方法

$REPOS/commit.lock というファイルを作成するとリポジトリに対する全ての commit が禁止される。

$ touch $REPOS/commit.lock
この状態でクライアントから commit を実行すると、クライアント側には "Service temporary unavailable." というメッセージが表示され commit が失敗する。 $REPOS/commit.lock を削除すれば再度 commit が可能になる。

commit 以外の更新処理

私のところでは commit 以外の更新系処理に関しても同様にリポジトリの保守前にアクセス制限をかけている。 それぞれのリポジトリフックは以下の通り。下記のリポジトリフックを使用した場合、

  • $REPOS/access.lock ・・・ commit, revporp, lock, unlock を全て禁止
  • $REPOS/commit.lock ・・・ commit を禁止
  • $REPOS/revporp.lock ・・・ revprop を禁止
  • $REPOS/lock.lock ・・・ lock を禁止
  • $REPOS/unlock.lock ・・・ unlock を禁止
となる。

$REPOS/hooks/start-commit

#!/bin/sh

REPOS="$1"
USER="$2"

if [ -e "$REPOS/access.lock" -o -e "$REPOS/commit.lock" ];
then
  echo "Service temporary unavailable." 1>&2
  exit 1
fi 
exit 0

$REPOS/hooks/pre-revprop-change

#!/bin/sh

REPOS="$1"
REV="$2"
USER="$3"
PROPNAME="$4"

if [ -e "$REPOS/access.lock" -o -e "$REPOS/revprop.lock" ];
then
  echo "Service temporary unavailable." 1>&2
  exit 1
fi

if [ "$PROPNAME" = "svn:log" ]; then exit 0; fi
exit 1

$REPOS/hooks/pre-lock

#!/bin/sh

REPOS="$1"
FILE="$2"
USER="$3"

if [ -e "$REPOS/access.lock" -o -e "$REPOS/lock.lock" ];
then
  echo "Service temporary unavailable." 1>&2
  exit 1
fi

exit 0

$REPOS/hooks/pre-unlock

#!/bin/sh

REPOS="$1"
FILE="$2"
USER="$3"

if [ -e "$REPOS/access.lock" -o -e "$REPOS/unlock.lock" ];
then
  echo "Service temporary unavailable." 1>&2
  exit 1
fi

exit 0

Posted in Subversion | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 21, 2008

[Subversion] Subversion リポジトリのお掃除

Subversion を長く使っていると、Subversion のトランザクションが走っている状態で Eclipse が落ちたりネットワークが切れたりして、トランザクションが未完の状態で切れてしまうことがある。 こういったトランザクションはクライアントからは分からないが、 サーバ側に「死んだトランザクション」として残っている。 「死んだトランザクション」が残っているからといって別段問題があるわけではないのだけれど、 不要なものがサーバに溜まっていくというのも気持ち悪いので、たまにチェックして要らないものを消している。

svnadmin lstxns
http://subversion.bluegate.org/doc/re40.html
リポジトリのお掃除
http://subversion.bluegate.org/doc/ch05s03.html#svn.reposadmin.maint.cleanup

「死んだトランザクション」の対応方法は以下の通り。

「死んだトランザクション」の確認

「死んだトランザクション」は "svnadmin lstxns" コマンドで確認することができる。 以下では Subversion リポジトリが "/my/svn/repos" にあることを前提とする。

まずは「死んだトランザクション」の一覧を取得する。

$ svnadmin lstxns /my/svn/repos
7867-1
5511-1
5511-2
5676-1
$
次に「死んだトランザクション」の内容を確認して削除しても良いものであるか否かを判断する。
$ svnlook info /my/svn/repos --transaction 7867-1
me
2008-09-19 20:14:39 +0900 (Fri, 19 Sep 2008)
0
commit comment
$
死んだトランザクションを一つずつ確認していくのが面倒なので、普通は for で一気に表示する。
$ for i in `svnadmin lstxns /my/svn/repos`; do echo "*** $i"; svnlook info /my/svn/repos --transaction $i; done
*** 7867-1 
me
2008-09-19 20:14:39 +0900 (Fri, 19 Sep 2008)
0
commit comment
*** 5511-1 
colleague
2008-09-04 16:35:53 +0900 (Tue, 04 Sep 2008)
0
commit comment
*** 5511-2 
colleague
2008-09-04 16:42:18 +0900 (Tue, 04 Sep 2008)
0
commit comment
*** 5676-1 
me
2008-09-12 14:29:26 +0900 (Fri, 12 Sep 2008)
61
commit comment

「死んだトランザクション」の削除

削除しても良い「死んだトランザクション」があったら、"svnadmin rmtxns" コマンドで削除する。 "svnadmin rmtxns" を実行する前に Subversion リポジトリに対する外部からのアクセスを禁止しておくこと。

# svnadmin rmtxns /my/svn/repos 5676-1
Transaction '5676-1' removed.
#
"svnadmin rmtxns" コマンドが正常終了したら、本当に削除されたか確認しておく。
$ svnadmin lstxns /my/svn/repos
7867-1
5511-1
5511-2
$

Posted in Subversion | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 20, 2008

[Misc] jQuery で "selected プロパティを設定できませんでした。未定義のエラーです。" エラー

Windows XP SP3 + IE6 の環境で、jQuery を使用して select タグ内の option を操作すると "selected プロパティを設定できませんでした。未定義のエラーです。" というエラーが発生する。 調べてみたところ、jQuery の既知のバグの様だ。 ちなみに、IE7 on Windows XP SP3 や Firefox on Mac OS X では発生しなかった。
この問題に関しては むつらつれづれさんの「jQueryでoption要素を追加した際の諸問題」というエントリに原因から解決策まで書いてある。多謝。

私は

option要素を増やした直後に
$('#target').width();
で回避した。

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 17, 2008

[Linux] GNU date コマンドで来月の日付を取得する方法をメモ

GNU date コマンドで来月の日付を取得する方法をメモしておく。 使用した GNU date コマンドのバージョンは以下の通り。

$ date --version
date (coreutils) 5.2.1
Written by David MacKenzie.

Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[参考訳]
これはフリーソフトウェアです. コピーの条件についてはソースをお読みください.
市場性及び特定目的適合性の如何によらず, いかなる保証もありません.

1 年後、1 年前などの日付を取得するには "year" もしくは "years" が使用できる。

$ date +"%Y%m%d" --date "1 year"
20091017
$ date +"%Y%m%d" --date "1 years"
20091017
$ date +"%Y%m%d" --date "10 years"
20181017
$ date +"%Y%m%d" --date "1 year ago"
20071017
$ date +"%Y%m%d" --date "1 years ago"
20071017
$ date +"%Y%m%d" --date "10 years ago"
19981017

1 ヶ月後、1 ヶ月前などの日付を取得するには "month" もしくは "months" が使用できる。

$ date +"%Y%m%d" --date "1 month"
20081117
$ date +"%Y%m%d" --date "1 months"
20081117
$ date +"%Y%m%d" --date "10 month"
20090817
$ date +"%Y%m%d" --date "1 month ago"
20080917
$ date +"%Y%m%d" --date "1 months ago"
20080917
$ date +"%Y%m%d" --date "10 month ago"
20071217

1 週間後、1 週間前などの日付を取得するには "week" もしくは "weeks" が使用できる。

$ date +"%Y%m%d" --date "1 week"
20081024
$ date +"%Y%m%d" --date "1 weeks"
20081024
$ date +"%Y%m%d" --date "10 weeks"
20081226
$ date +"%Y%m%d" --date "1 week ago"
20081010
$ date +"%Y%m%d" --date "1 weeks ago"
20081010
$ date +"%Y%m%d" --date "10 weeks ago"
20080808

1 日後、1 日前などの日付を取得するには "day" もしくは "days" が使用できる。

$ date +"%Y%m%d" --date "1 day"
20081018
$ date +"%Y%m%d" --date "1 days"
20081018
$ date +"%Y%m%d" --date "200 days"
20090505
$ date +"%Y%m%d" --date "1 day ago"
20081016
$ date +"%Y%m%d" --date "1 days ago"
20081016
$ date +"%Y%m%d" --date "300 days ago"
20071222

その他(時間、分、秒)

時間であれば "hour", "hours"、分であれば "minute", "minutes"、秒であれば "second", "seconds" で上記と同様のことができる。

`man date` より関連部分を抜粋

date(1)

名前
       date - システムの日付と時刻を表示・設定する

書式
       date  [-uR]  [-d  datestr]  [-f  datefile]  [-r file] [-s datestr] [-I
       [timespec]] [--date=datestr] [--file=datefile] [--iso-8601[=timespec]]
       [--reference=file]  [--set=datestr]  [--rfc-822] [--universal] [--utc]
       [+format] [MMDDhhmm[[CC]YY][.ss]]

       date [--help] [--version]

  (略)

   時刻フィールド
       %H     時 (00..23)
       %I     時 (01..12)
       %k     時 (0..23)
       %l     時 (1..12)
       %M     分 (00..59)
       %p     AM あるいは PM のロケール
       %r     時刻、12 時間 (hh:mm:ss [AP]M)
       %s     1970-01-01 00:00:00 UTC からの秒数 (標準外の拡張)
       %S     秒 (00..60)
       %T     時刻、24 時間 (hh:mm:ss)
       %X     ロケールによる時刻の表現 (%H:%M:%S)
       %Z     タイムゾーン (例 EDT)、あるいはタイムゾーンが決定できないならば
              無し

   日付フィールド
       %a     ロケールの省略形の曜日名 (Sun..Sat)
       %A     ロケールの完全表記の曜日名、可変長 (Sunday..Saturday)
       %b     ロケールの省略形の月名 (Jan..Dec)
       %B     ロケールの完全表記の月名、可変長 (January..December)
       %c     ロケールの日付と時刻 (Sat Nov 04 12:02:33 EST 1989)
       %d     月内通算日数 (01..31)
       %D     日付 (mm/dd/yy)
       %h     %b と同じ
       %j     年内通算日数 (001..366)
       %m     月 (01..12)
       %U     日曜日を週の最初の日とした年内通算週 (00..53)
       %w     週のうちの曜日 (0..6) (0 が日曜日)
       %W     月曜日を週の最初の日とした年内通算週 (00..53)
       %x     ロケールの日付表現 (mm/dd/yy)
       %y     年の最後の 2 つの数字 (00..99)
       %Y     年 (1970...)

  (略)

    -d datestr, --date datestr
              現在の時刻・日付の代わりに、 datestr で指定された時刻・日付を表
              示する。 datestr は普通のフォーマットならだいたいなんでも使うこ
              とができる。月名、タイムゾーン、‘am’ や ‘pm’ なども用いてよい。

  (略)

例
       一昨日の日付を表示するには:
              date --date ´2 days ago´

       3 ヶ月と 1 日後の日付を表示するには:
              date --date ´3 months 1 day´

       今年のクリスマスが年の初めから何日目かを表示するには:
              date --date ´25 Dec´ +%j
  (略)

Posted in Linux | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 14, 2008

[Misc] WEP の完全な終焉

WEP によるセキュリティが誰にでも簡単に破れてしまう時代がやって来た様だ。 一年程前に WEP を 1 分で破ることが出来るという論文が発表されていたが、今回は 10 秒程度で破ることが出来、しかもその作業に特殊な制約が要らないという恐ろしい論文が発表された。 とりあえず前回と今回の論文に関する情報を集めてみた。

2008 の論文 : "現実的なWEPの鍵導出法"

CSS2008において,WEPを一瞬にして解読する方法を提案しました.
http://srv.prof-morii.net/~morii/#CSS20081009
我々の方法を用いることによって,任意のIPパケットを1万パケットから2万パケット収集することによって,WEP鍵(104ビット)を導出することが可能です.数年前からWEPの危険性が指摘されているとはいえ,現在でも多くの組織,機関,企業,それに個人がWEPを利用しています. 無線LANを導入している企業の50%以上がWEPを利用しているという報告 もあります.現実にはWEPが今だ利用されているわけです.この主たる理由は,脆弱性があるとはいえ,実際には瞬時に解くことはできず,それなりの準備と不正アクセスを行う等の能動的な攻撃(行為)が必要であり,簡単には解けなかったのです.我々が提案した方法によって,安価なノートパソコンを用いて,簡単にWEP の104ビット鍵を導出することができるようになりました.

一般的な環境で10秒でWEPを解読できる手法が登場
http://slashdot.jp/security/08/10/14/0726252.shtml
一瞬にして無線LANのWEPを解読する方法がついに登場、まもなく解読プログラムを公開予定
http://gigazine.net/index.php?/news/comments/20081013_wep_morii/

2007 年の論文 : "Breaking 104 bit WEP in less than 60 seconds"

Breaking 104 bit WEP in less than 60 seconds
http://eprint.iacr.org/2007/120.pdf
We demonstrate an active attack on the WEP protocol that is able to recover a 104-bit WEP key using less than 40,000 frames with a success probability of 50%. In order to succeed in 95% of all cases, 85,000 packets are needed. The IV of these packets can be randomly chosen. This is an improvement in the number of required frames by more than an order of magnitude over the best known key-recovery attacks for WEP. On a IEEE 802.11g network, the number of frames required can be ob- tained by re-injection in less than a minute. The required computational effort is approximately 220 RC4 key setups, which on current desktop and laptop CPUs is negligible.

aircrack-ptw
http://www.cdc.informatik.tu-darmstadt.de/aircrack-ptw/
104ビットWEPは1分あれば破れる
http://slashdot.jp/security/07/04/03/2243222.shtml
「104ビットのWEPを60秒足らずで破る」論文が公開
http://www.atmarkit.co.jp/news/200704/05/wep.html
暗号化技術WEP、今度こそ最期を迎えるか
http://www.atmarkit.co.jp/news/200704/09/wep.html

WEP の危険性に関する情報

Stop using WEP encryption!
http://www.sophos.com/blogs/gc/g/2008/10/08/stop-using-wep-encryption/
Tips for securing your wireless connection
http://www.sophos.com/security/best-practice/wi-fi.html
英Sophos、WEPの利用禁止を呼びかけ
http://internet.watch.impress.co.jp/cda/news/2008/10/09/21123.html

さて、ではどうしようか

これで、Nindo DS が 2000 万台以上出荷されている我が国は、国内全土がフリースポット化されたわけだ。 便利な世の中と言えなくもないが、流石に見ず知らずの人間が自宅内 LAN にローカルアクセスしてくるのは避けたい。 とは言え、Nintendo DS、Wii のネットアクセスも捨てがたい、という場合にはどうしたら良いだろうか?

  • Mac アドレスフィルタリングを使う。
  • ルータを 3 台設置する。
    1. ISP に直接接続されるルータ (A)。無線 LAN は使用しない。
    2. 自宅内 LAN 環境を提供するルータ (B)。ルータ A にぶら下がる。無線 LAN は WPA2 などセキュアなものを使用。ルータ C からのパケットは受け付けない。
    3. WEP 環境を提供するルータ (C)。ルータ A にぶら下がる。セキュアではないという前提で利用。
Mac アドレスは詐称できるのでルータ C への侵入は防ぎようがないが、少なくともルータ B のセグメントはかなり安心して使用できる。 現実的にはこの程度が妥協点だろうか。 無線 LAN クライアント毎に接続方式を変えるルータも発売されている様なので、費用対効果を考えればこれを使用するという手もある。 「WEP接続子機からAES/TKIP接続子機にアクセスできないよう制限可能」と書いてあるし。 ただ、ソフトウェアレベルでの制限だろうからどこまで信用できるのか、というのは気になるところではある。 やはりルータを複数台設置する方が個人的には良さそうだ。

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 07, 2008

[Maven] Maven2 の release プラグインにチャレンジ

Maven2 では maven-release-plugin を使用することで簡単にリリース作業を行うことができる。 maven-release-plugin を使うことで、

  • SCM のタグ付け
  • pom.xml の <version> 更新
  • Maven リポジトリへのプロジェクト登録
  • Web サーバへのドキュメント登録

を簡単に行うことができる。

Maven Release Plugin
http://maven.apache.org/plugins/maven-release-plugin/
Technical Project Descriptor
http://maven.apache.org/ref/current/maven-model/maven.html
Technical Settings Descriptor
http://maven.apache.org/ref/current/maven-settings/settings.html

環境

サーバ環境

サーバは "dev.example.com" と表記し、以下の環境であることを前提とする。

  • http://dev.example.com/project/maven で WebDAV が利用可能。
  • http://dev.example.com/project/maven-snapshot で WebDAV が利用可能。
  • http://dev.example.com/project/dist で WebDAV が利用可能。
  • http://dev.example.com/project/svn で Subversion にアクセス可能。

クライアント環境

クライアントの環境はこんな感じ。Maven2 と svn コマンドが動作するだけで良いはず。

$ mvn --version
Maven version: 2.0.9
Java version: 1.5.0_13
OS name: "mac os x" version: "10.4.11" arch: "i386" Family: "unix"
$ svn --version
svn, version 1.5.1 (r32289)
   compiled Aug  6 2008, 13:59:27

Copyright (C) 2000-2008 CollabNet.
Subversion is open source software, see http://subversion.tigris.org/
This product includes software developed by CollabNet (http://www.Collab.Net/).

The following repository access (RA) modules are available:

* ra_neon : Module for accessing a repository via WebDAV protocol using Neon.
  - handles 'http' scheme
  - handles 'https' scheme
* ra_svn : Module for accessing a repository using the svn network protocol.
  - with Cyrus SASL authentication
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme
* ra_serf : Module for accessing a repository via WebDAV protocol using serf.
  - handles 'http' scheme
  - handles 'https' scheme
$

設定

pom.xml

$PROJECT_HOME/pom.xml に release 用の設定を行う。

  • scm の設定
  • distributionManagement の設定
  • maven-release-plugin の組み込み
  • (Web DAV を利用する場合は) wagon-webdav の組み込み
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>jp.in-vitro.dummy</groupId>
  <artifactId>dummy</artifactId>
  <version>1.0.1-SNAPSHOT</version>
  <name>Dummy</name>
  <description>Dummy Project</description>
  <packaging>jar</packaging>

  <scm>
    <url>http://dev.example.com/project/svn/Dummy/tags/dummy-1.0.0</url>
    <connection>scm:svn:http://dev.example.com/project/svn/Dummy/tags/dummy-1.0.0</connection>
    <developerConnection>scm:svn:http://dev.example.com/project/svn/Dummy/tags/dummy-1.0.0</developerConnection>
  </scm>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-release-plugin</artifactId>
        <configuration>
          <username>${scm.username}</username>
          <password>${scm.password}</password>
        </configuration>
      </plugin>
    </plugins>
    <extensions>
      <extension>
        <groupId>org.apache.maven.wagon</groupId>
        <artifactId>wagon-webdav</artifactId>
      </extension>
    </extensions>
  </build>

  <distributionManagement>
    <repository>
      <id>project.repository.release</id>
      <name>Project Repository</name>
      <url>dav:http://dev.example.com/project/maven</url>
    </repository>
    <snapshotRepository>
      <id>project.repository.snapshots</id>
      <uniqueVersion>false</uniqueVersion>
      <name>Project Snapshots Repository</name>
      <url>dav:http://dev.example.com/project/maven-snapshot</url>
    </snapshotRepository>
    <site>
      <id>project.website</id>
      <url>dav:http://dev.example.com/project/dist/${pom.version}</url>
    </site>
  </distributionManagement>
</project>

settings.xml の設定

$USER_HOME/.m2/settings.xml に SCM や Web DAV のアカウント情報を記述する。

<?xml version="1.0" encoding="UTF-8" ?>

<settings xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <servers>
    <server>
      <id>project.repository.release</id>
      <username>me</username>
      <password>password</password>
    </server>
    <server>
      <id>project.repository.snapshots</id>
      <username>me</username>
      <password>password</password>
    </server>
    <server>
      <id>project.website</id>
      <username>me</username>
      <password>password</password>
    </server>
  </servers>

  <profiles>
    <profile>
      <id>project</id>
      <properties>
        <scm.username>me</scm.username>
        <scm.password>password</scm.password>
      </properties>
    </profile>
  </profiles>

  <activeProfiles>
    <activeProfile>project</activeProfile>
  </activeProfiles>
</settings>

maven-release-plugin の実行

release:prepare

まずはリリースの準備として release:prepare を実行する。 release:prepare では、"リリースするバージョン"、"SCM に付けるタグ", "次のバージョン" を質問されるので、それぞれ入力する。

$ mvn release:prepare
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'release'.
WAGON_VERSION: 1.0-beta-2
[INFO] ------------------------------------------------------------------------
[INFO] Building Dummy
[INFO]    task-segment: [release:prepare] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [release:prepare]
[INFO] Verifying that there are no local modifications...
[INFO] Executing: svn --username me --password ***** --non-interactive status
[INFO] Working directory: /Users/me/Documents/Private/000-workspace/Dummy
[INFO] Checking dependencies and plugins for snapshots ...
What is the release version for "Dummy"? (jp.in-vitro.dummy:dummy) 1.0.1: : 
What is SCM release tag or label for "Dummy"? (jp.in-vitro.dummy:dummy) dummy-1.0.1: : 
What is the new development version for "Dummy"? (jp.in-vitro.dummy:dummy) 1.0.2-SNAPSHOT: : 
[INFO] Transforming 'Dummy'...
[INFO] Not generating release POMs
[INFO] Executing goals 'clean verify'...
  (略)
[INFO] Release preparation complete.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 17 seconds
[INFO] Finished at: Fri Oct 03 18:20:48 JST 2008
[INFO] Final Memory: 6M/12M
[INFO] ------------------------------------------------------------------------
$

release:perform

release:prepare が正常終了したら、release:perform を実行する。 release:perform を実行すると、SCM へのタグ付けやリポジトリへの登録、バージョンの更新などのリリース処理が行われる。

$ mvn release:perform
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'release'.
WAGON_VERSION: 1.0-beta-2
[INFO] ------------------------------------------------------------------------
[INFO] Building Dummy
[INFO]    task-segment: [release:perform] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [release:perform]
[INFO] Checking out the project to perform the release ...
[INFO] Executing: svn --username me --password ***** --non-interactive checkout http://dev.example.com/project/svn/Dummy/tags/dummy-1.0.1 checkout
[INFO] Working directory: /Users/me/Documents/Private/000-workspace/Dummy/target
[INFO] Executing goals 'deploy site-deploy'...
[INFO] Executing: mvn deploy site-deploy --no-plugin-updates -P project -DperformRelease=true -f pom.xml
[INFO] Scanning for projects...
        WAGON_VERSION: 1.0-beta-2
        [INFO] ------------------------------------------------------------------------
        [INFO] Building Dummy
        [INFO]    task-segment: [deploy, site-deploy]
        [INFO] ------------------------------------------------------------------------
        [INFO] [resources:resources]
        [INFO] Using default encoding to copy filtered resources.
        [INFO] [compiler:compile]
  (略)
        Transfer finished. 1687 bytes copied in 0.025 seconds
        http://dev.example.com/project/dist/1.0.1 - Session: Disconnecting  
        http://dev.example.com/project/dist/1.0.1 - Session: Disconnected
        [INFO] ------------------------------------------------------------------------
        [INFO] BUILD SUCCESSFUL
        [INFO] ------------------------------------------------------------------------
        [INFO] Total time: 1 minute 2 seconds
        [INFO] Finished at: Fri Oct 03 18:22:01 JST 2008
        [INFO] Final Memory: 39M/63M
        [INFO] ------------------------------------------------------------------------
        [INFO] Cleaning up after release...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 8 seconds
[INFO] Finished at: Fri Oct 03 18:22:02 JST 2008
[INFO] Final Memory: 6M/12M
[INFO] ------------------------------------------------------------------------
$ 

Posted in Maven | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 06, 2008

Oct 05, 2008

[Apple] JAD を Mac OS X にインストール

Mac OS X に JAD をインストールしたときのメモ。 ・・・解凍して移動するだけなのだけれど。

Jad - the fast JAva Decompiler
http://www.kpdus.com/jad.html

JAD のインストール

$ sudo mv ./jad /usr/bin/
Password:
$ sudo chmod 755 /usr/bin/jad
$ jad
Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov (jad@kpdus.com).
Usage:    jad [option(s)] 
Options: -a       - generate JVM instructions as comments (annotate)
         -af      - output fully qualified names when annotating
         -b       - generate redundant braces (braces)
  (略)
         -t       - use tabs instead of spaces for indentation
         -v       - show method names while decompiling
$ 

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 04, 2008

[Misc] Eclipse 3.5 メモ

気付いたら Eclipse 3.5 も既に M2 が出ていた。 M2 なので乗り換えるわけにはいかないが、とりあえずどういう機能が追加されているのか確認してみた。

eclipse project downloads
http://download.eclipse.org/eclipse/downloads/
Eclipse 3.5 M1 - New and Noteworthy
http://download.eclipse.org/eclipse/downloads/drops/S-3.5M1-200808071402/3.5M1/eclipse-news-M1.html
Eclipse 3.5 M2 - New and Noteworthy
http://download.eclipse.org/eclipse/downloads/drops/S-3.5M2-200809180100/eclipse-news-M2.html

今のところ、個人的に嬉しい機能は特に追加されていないな。

試しにダウンロードしてみたら、3.5M2 では Subclipse がインストールできなかった。

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 03, 2008

[Apple] Darwine メモ

Darwine は Wine を Mac OS X 用に port したもの。 いい加減秀丸エディタを使うためだけに Parallels & Windows XP を起動するのに疲れたので、Darwine で秀丸エディタが使えないか試してみた。

Darwine
http://darwine.sourceforge.net/
Darwine Builds for OS X
http://www.kronenberg.org/darwine/

Darwine のインストール

Sourceforge の Darwine より Darwine Builds for OS X の方がバージョンが新しいので、そちらを使ってみる。 今回使用したのは Darwine-x86-1.1.5.dmg。 インストール自体は非常に簡単。 dmg をマウントして Darwine と TRIX.app を /Applications にドラッグするだけ。
[Darwine 01]

フォントのインストール

Darwine で使用するフォントをインストールする。 TRIX を使うとフォントを簡単にインストールすることができる。
[TRIX]

フォントを手動でインストールする場合は /Applications/Darwine/Wine.bundle/Contents/share/wine/fonts/ にフォントをコピーすれば良い。

秀丸エディタの実行

/Applications/Darwine/WineHelper.app に hidemaru.exe をドロップすると秀丸エディタが起動する。
[秀丸エディタが起動した]

起動したのは良いのだけれど、日本語入力が出来ない。 どうやら Darwine ではことえりや ATOK での入力が出来ない様だ。 ・・・Darwine の今後のバージョンアップに期待しつつ Parallels を使うしかないな。 秀丸エディタの Mac OS X 版が出ないかな。

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 02, 2008

Oct 01, 2008

[Misc] FireFox のアドオンをメモ

FireFox で重宝しているアドオンをメモしておく。

Firebug
Web Development Evolved.
https://addons.mozilla.org/ja/firefox/addon/1843
Flashblock
Replaces Flash objects with a button you can click to view them.
https://addons.mozilla.org/ja/firefox/addon/433
Live HTTP headers
ウェブページとブラウジング中の HTTP ヘッダを表示します。
https://addons.mozilla.org/ja/firefox/addon/3829
NoScript
Extra protection for your Firefox: NoScript allows JavaScript, Java (and other plugins) only for trusted domains of your choice (e.g. your home-banking web site).
https://addons.mozilla.org/ja/firefox/addon/722
SearchStatus
Display the Google PageRank and Alexa ranking with search-related tools.
https://addons.mozilla.org/ja/firefox/addon/321
Selenium IDE
Record, edit and play Selenium tests.
https://addons.mozilla.org/ja/firefox/addon/2079
Server Switcher
開発と本番のサーバを切り替えます。
https://addons.mozilla.org/ja/firefox/addon/2409
User Agent Switcher
Adds a menu and a toolbar button to switch the user agent of the browser.
https://addons.mozilla.org/ja/firefox/addon/59
Web Developer
Adds a menu and a toolbar with various web developer tools.
https://addons.mozilla.org/ja/firefox/addon/60

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 30, 2008

[Apple] Perian メモ

Perian is a free, open source QuickTime component that adds native support for many popular video formats.
Perian
http://www.perian.org/
SupportedFormats
http://trac.perian.org/wiki/SupportedFormats

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 17, 2008

[Linux] tar 実行時に不思議なエラーに遭遇

tar 実行時に不思議なエラーに遭遇した。

tar: Only wrote 2047 of 10240 bytes to ./dummy.tar
tar: Error is not recoverable: exiting now
色々調べてようやく原因が分かった。 2Gbyte 以上のファイルを生成できないプラットフォームで、tar ファイルが 2Gbyte を超えた為に発生していたらしい。 余りに便利になりすぎて、一昔前の制約をどんどん忘れていく今日この頃。 幸せなことだけれど、たまにこういう落とし穴にはまる orz

ちなみに、発生したのはかなり昔の LinkStation 上。

Posted in Linux | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 14, 2008

[Apple] Mac OS X に Subversion をインストール

コマンドラインから svn コマンドを使用したいので、Mac OS X (Tiger) に Subversion をインストールした。

MacPorts でインストールしようと思ったが、エラーが発生してインストールできなかった。

make[1]: *** [buckets/apr_brigade.lo] Error 1
make: *** [all-recursive] Error 1
プログラマの道具箱 さんのエントリ mac portsでsubversionをインストール に記述のあった "sudo port upgrade apr" を試してみたが、apr の更新自体でエラーが発生する始末。

結局 MacPorts でのインストールは諦め、Mac OS X 用のバイナリを DMG で入手してインストールした。 今回は openCollabNet から Subversion 1.5.1-2 Universal.dmg を使用した。

openCollabNet
http://www.collab.net/downloads/community/
普通にインストーラを使用してインストールを実施。 問題なく svn コマンドが使用できる様になった。
$ /usr/local/bin/svn --version
svn, version 1.5.1 (r32289)
   compiled Aug  6 2008, 13:59:27

Copyright (C) 2000-2008 CollabNet.
Subversion is open source software, see http://subversion.tigris.org/
This product includes software developed by CollabNet (http://www.Collab.Net/).

The following repository access (RA) modules are available:

* ra_neon : Module for accessing a repository via WebDAV protocol using Neon.
  - handles 'http' scheme
  - handles 'https' scheme
* ra_svn : Module for accessing a repository using the svn network protocol.
  - with Cyrus SASL authentication
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme
* ra_serf : Module for accessing a repository via WebDAV protocol using serf.
  - handles 'http' scheme
  - handles 'https' scheme

$
それにしても、最近 MacPorts でエラーばかり起きる。 調子が悪いのだろうか・・・。

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 13, 2008

[Apple] MacPorts のアップデートに失敗する

Mac OS X 10.4 で久しぶりに MacPorts のアップデートを行ったところ、"error: Broken X11 install. No X11 headers" というエラーが発生した。 X11SDK はインストール済みなので、"No X11 headers" ということは無いはずなのだけれど。 X11SDk を再インストールして再挑戦することに。

$ sudo port selfupdate
Password:
MacPorts base version 1.520 installed
Downloaded MacPorts base version 1.600
Configuring, Building and Installing new MacPorts base
Error: /opt/local/bin/port: selfupdate failed: Error installing new MacPorts base: shell command "cd /opt/local/var/macports/sources/rsync.macports.org/release/base && ./configure --prefix=/opt/local --with-install-user=root --with-install-group=admin --with-tclpackage=/Library/Tcl && make && make install" returned error 1
Command output: checking for working vfork... (cached) yes
checking whether strerror_r is declared... yes
checking for strerror_r... yes
checking whether strerror_r returns char *... no
checking for bzero... yes
  (略)
checking for openssl/md5.h... yes
checking for X... no
checking for XOpenDisplay in -lX11... yes
Please install the X11 SDK packages from the
Xcode Developer Tools CD
configure: error: Broken X11 install. No X11 headers
$
"Mac OS X Instal Disc 1" から X11SDK を再インストールしたところ、
[X11SDKインストールに失敗]
というエラーでインストールできない。 X11SDK が既にインストールされているのが原因の様だ。
$ rm /Library/Receipts/X11SDK.pkg
X11SDK をインストーラが検知できない様に上記の通り pkg ファイルを削除して再度実行したところ正常にインストールが終了した。 続いて MacPorts のアップデートに再挑戦。
$ sudo port selfupdate
Password:
MacPorts base version 1.520 installed
Downloaded MacPorts base version 1.600
Configuring, Building and Installing new MacPorts base
selfupdate done!
$ sudo port version
Version: 1.600
今度は上手くいった。やれやれ。

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 12, 2008

[Apple] フォルダアクションで docbook を PDF に変換する

Mac OS X 上に Docbook 環境を構築してみた。 やりたいのは、フォルダアクションで docbook を PDF 化すること。

docbook 環境のインストール

まずは MacPorts を使用して docbook 関連のライブラリと Apache FOP をインストールする。

$ sudo port install docbook-xml docbook-xsl libxslt fop
Password:
--->  Fetching xmlcatmgr
  (略)
--->  Installing xmlcatmgr 2.2_1
--->  Activating xmlcatmgr 2.2_1
--->  Cleaning xmlcatmgr
--->  Fetching docbook-xml-4.1.2
  (略)
--->  Installing docbook-xml-4.1.2 4.1.2_1
--->  Activating docbook-xml-4.1.2 4.1.2_1
--->  Cleaning docbook-xml-4.1.2
  (略)
--->  Installing docbook-xml-4.2 4.2_0
--->  Activating docbook-xml-4.2 4.2_0
--->  Cleaning docbook-xml-4.2
--->  Fetching docbook-xml-4.3
  (略)
--->  Installing docbook-xml-4.3 4.3_0
--->  Activating docbook-xml-4.3 4.3_0
--->  Cleaning docbook-xml-4.3
--->  Fetching docbook-xml-4.4
  (略)
--->  Installing docbook-xml-4.4 4.4_0
--->  Activating docbook-xml-4.4 4.4_0
--->  Cleaning docbook-xml-4.4
--->  Fetching docbook-xml-4.5
  (略)
--->  Installing docbook-xml-4.5 4.5_0
--->  Activating docbook-xml-4.5 4.5_0
--->  Cleaning docbook-xml-4.5
--->  Fetching docbook-xml
  (略)
--->  Installing docbook-xml 4.5_1
--->  Activating docbook-xml 4.5_1
--->  Cleaning docbook-xml
--->  Fetching docbook-xsl
  (略)
--->  Installing docbook-xsl 1.72.0_0
--->  Activating docbook-xsl 1.72.0_0
--->  Cleaning docbook-xsl
--->  Fetching libxslt
  (略)
--->  Installing libxslt 1.1.22_0
--->  Activating libxslt 1.1.22_0
--->  Cleaning libxslt
--->  Fetching fop
  (略)
--->  Installing fop 0.94_0
--->  Activating fop 0.94_0
--->  Cleaning fop
$

シングルバイトの docbook ファイルを PDF 化してみる

PDF の Font 周りは面倒なので、とりあえずはシングルバイト文字のみで PDF 化を試してみる。 用意したデータはこんな感じ。

<?xml version="1.0" encoding="UTF-8"?>

<book id="my_test_book">
  <title>my test book</title>
  <chapter id="chapter1">
    <title>Chapter 1</title>
    <para>Hello docbook!</para>
  </chapter>
  <chapter id="chapter2">
    <title>Chapter 2</title>
    <para>This is single byte docbook document.</para>
  </chapter>
</book>
docbook xml → (XSLT) → FO → (Apache FOP) → PDF という様に docbook を PDF に変換する。
$ /opt/local/bin/xsltproc -o ./test.fo /opt/local/share/xsl/docbook-xsl/fo/docbook.xsl ./test.xml
Making portrait pages on USletter paper (8.5inx11in)
$ fop -fo ./test.fo -pdf ./test.pdf
2008/09/10 11:45:21 org.apache.fop.hyphenation.Hyphenator getHyphenationTree
致命的: Couldn't find hyphenation pattern en
$ 
何事もなく PDF が生成された。
[PDF 化されたシングルバイト docbook]

マルチバイトの docbook ファイルを PDF 化してみる

次に本命のマルチバイト docbook ファイルの変換に挑戦してみる。 FOP のフォント設定は以下のサイトを参考にさせていただいた。感謝。

Apache FOP: Fonts
http://xmlgraphics.apache.org/fop/0.95/fonts.html#basics
DocBook メモ
http://cueplot.sourceforge.jp/wiki/index.php?DocBook%20%E3%83%A1%E3%83%A2
用意したデータはこんな感じ。
<?xml version="1.0" encoding="UTF-8"?>

<book id="my_test_book_ja">
  <title>テストブック</title>
  <chapter id="chapter1">
    <title>第一章</title>
    <para>やぁ! Docbook</para>
  </chapter>
  <chapter id="chapter2">
    <title>第二章</title>
    <para>日本語は上手く表示できるかな?</para>
  </chapter>
</book>
当然駄目だと分かっているが、とりあえずそのまま PDF 化してみる。 手順はシングルバイトのときと全く同様。
結果は
[やはり駄目]

やはり Font を設定しなければ化けることが分かったので、仕方なく Font を設定する。 手順は上記のサイトに記載がある通り。

$ cd /opt/local/share/java/fop/0.94/
$ java -cp ./build/fop.jar:./lib/commons-logging-1.0.4.jar:./lib/commons-io-1.3.1.jar org.apache.fop.fonts.apps.TTFReader -d -fn "HiraginoMinchoProW3" "/System/Library/Fonts/\343\203\222\343\203\251\343\202\255\343\202\231\343\203\216\346\230\216\346\234\235 Pro W3.otf" ./hiraginominchoprow3.xml
TTF Reader for Apache FOP 0.94

Parsing font...
Reading /System/Library/Fonts/?q???L??m???? Pro W3.otf...
sfnt version: OpenType with CFF data
  (略)
Font Family: Hiragino Mincho Pro
Error while building XML font metrics file.
java.lang.UnsupportedOperationException: OpenType fonts with CFF data are not supported, yet
        at org.apache.fop.fonts.apps.TTFReader.loadTTF(TTFReader.java:214)
        at org.apache.fop.fonts.apps.TTFReader.main(TTFReader.java:163)
・・・ ヒラギノは現時点の Apache FOP では扱えないらしい。 では、ということで、MS 明朝を試してみた。
$ java -cp ./build/fop.jar:./lib/commons-logging-1.0.4.jar:./lib/commons-io-1.3.1.jar org.apache.fop.fonts.apps.TTFReader -d -fn "MSMINCHO" "./fonts/MSMINCHO.TTF" ./fonts/msmincho.xml
TTF Reader for Apache FOP 0.94

Parsing font...
Reading /fonts/MSMINCHO.TTF...
sfnt version: OpenType 1.0
  (略)
Font Family: MS Mincho
Creating xml font file...
Creating CID encoded metrics...
Writing xml font file /fonts/msmincho.xml...
This font contains no embedding license restrictions.

XML font metrics file successfully created.
$ 
MS 明朝は正常に読み込むことができた。
後は FOP の設定ファイル fop.xconf を作成するだけ。
<?xml version="1.0"?>
<fop version="1.0">
 <renderers>
   <renderer mime="application/pdf">
     <fonts>
       <font metrics-url="/fonts/msmincho.xml" kerning="yes" embed-url="/fonts/MSMINCHO.ttf">
         <font-triplet name="MSMINCHO" style="normal" weight="100"/>
         <font-triplet name="MSMINCHO" style="normal" weight="200"/>
         <font-triplet name="MSMINCHO" style="normal" weight="300"/>
         <font-triplet name="MSMINCHO" style="normal" weight="400"/>
         <font-triplet name="MSMINCHO" style="normal" weight="500"/>
         <font-triplet name="MSMINCHO" style="normal" weight="600"/>
         <font-triplet name="MSMINCHO" style="normal" weight="700"/>
         <font-triplet name="MSMINCHO" style="normal" weight="800"/>
         <font-triplet name="MSMINCHO" style="normal" weight="900"/>
       </font>
     </fonts>
   </renderer>
 </renderers>
</fop>

ではマルチバイト docbook の PDF 化に再挑戦。 今回は MS 明朝を使用するので、docbook から FO を作成した後で FO 内の Font 設定を変更する処理を入れる。 docbook → (XSLT) → fo → (sed) → fo → (FOP) → PDF という感じになる。 また、Apache FOP 実行時に上で作成した設定ファイルを指定する必要がある。

$ /opt/local/bin/xsltproc -o ./test_ja.fo /opt/local/share/xsl/docbook-xsl/fo/docbook.xsl ./test_ja.xml
Making portrait pages on USletter paper (8.5inx11in)
$ sed -e "s/font-family=\"/font-family=\"MSMINCHO,/g" ./test_ja.fo > ./test_ja_2.fo
$ fop -fo ./test_ja_2.fo -pdf ./test_ja_2.pdf -c ./fop.xconf 
2008/09/10 13:14:28 org.apache.fop.hyphenation.Hyphenator getHyphenationTree
?v???I: Couldn't find hyphenation pattern en
$ 
マルチバイト docbook の PDF 化に成功!!
[日本語も表示できた!!]

AppleScript で docbook → PDF の変換を行う

docbook の PDF 化に成功したところで、念願の AppleScript での変換を行う。 まずはシェルスクリプトを用意。

#!/bin/sh

DOCBOOK_XML=$1
DOCBOOK_PDF=$2

XSLTPROC=/opt/local/bin/xsltproc
DOCBOOK_XSLT=/opt/local/share/xsl/docbook-xsl/fo/docbook.xsl
FOP=/opt/local/bin/fop
FOP_CONFIG=/fonts/fop.xconf
WORKDIR=`pwd`
WORK_FO=$WORKDIR/tmp.fo
WORK_FO_CONVERTED=$WORKDIR/tmp_converted.fo

echo "Converting docbook -> PDF : $DOCBOOK_XML -> $DOCBOOK_PDF"

if [ ! -f "$DOCBOOK_XML" ];
  then
    echo "No docbook file found. : $DOCBOOK_XML"
    exit;
fi

rm "$WORK_FO" 2> /dev/null
rm "$WORK_FO_CONVERTED" 2> /dev/null

$XSLTPROC -o "$WORK_FO" "$DOCBOOK_XSLT" "$DOCBOOK_XML"
sed -e "s/font-family=\"/font-family=\"MSMINCHO,/g" "$WORK_FO" > "$WORK_FO_CONVERTED"
$FOP -fo "$WORK_FO_CONVERTED" -pdf "$DOCBOOK_PDF" -c "$FOP_CONFIG"

rm "$WORK_FO" 2> /dev/null
rm "$WORK_FO_CONVERTED" 2> /dev/null
次にこのシェルスクリプトを呼び出す AppleScript を用意する。 この AppleScript は "/Library/Scripts/Folder Action Scripts/Image - Duplicate as JPEG.scpt" を参考にさせていただいた(「参考に」と言うより、ほぼそのまま)。
property doneFoldername : "PDF"
property originalsFoldername : "Docbook"
property pdfExtension : "pdf"
property typeList : {"XML"}
property extensionList : {"xml"}

on adding folder items to thisFolder after receiving theseItems
  tell application "Finder"
    if not (exists folder doneFoldername of thisFolder) then
      make new folder at thisFolder with properties {name:doneFoldername}
    end if
    set the resultsFolder to (folder doneFoldername of thisFolder) as alias
    if not (exists folder originalsFoldername of thisFolder) then
      make new folder at thisFolder with properties {name:originalsFoldername}
      set current view of container window of thisFolder to list view
    end if
    set the originalsFolder to folder originalsFoldername of thisFolder
  end tell
  try
    repeat with i from 1 to number of items in theseItems
      set thisItem to item i of theseItems
      set the itemInfo to the info for thisItem
      if (alias of the itemInfo is false and the file type of the itemInfo is in the typeList) or (the name extension of the itemInfo is in the extensionList) then
        tell application "Finder"
          my resolveConflicts(thisItem, originalsFolder, "")
          set the newName to my resolveConflicts(thisItem, resultsFolder, pdfExtension)
          set the SourceFile to (move thisItem to the originalsFolder with replacing) as alias
        end tell
        processItem(SourceFile, newName, resultsFolder)
      end if
    end repeat
  on error errorMessage number errorNumber
    if the errorNumber is not -128 then
      tell application "Finder"
        activate
        display dialog errorMessage buttons {"Cancel"} default button 1 giving up after 120
      end tell
    end if
  end try
end adding folder items to

on resolveConflicts(thisItem, targetFolder, newExtension)
  tell application "Finder"
    set the fileName to the name of thisItem
    set fileExtension to the name extension of thisItem
    if the fileExtension is "" then
      set the trimmedName to the fileName
    else
      set the trimmedName to text 1 thru -((length of fileExtension) + 2) of the fileName
    end if
    if the newExtension is "" then
      set targetName to fileName
      set targetExtension to fileExtension
    else
      set targetExtension to newExtension
      set targetName to (the trimmedName & "." & targetExtension) as string
    end if
    if (exists document file targetName of targetFolder) then
      set the nameIncrement to 1
      repeat
        set the newName to (the trimmedName & "." & (nameIncrement as string) & "." & targetExtension) as string
        if not (exists document file newName of the targetFolder) then
          set the name of document file targetName of the targetFolder to the newName
          exit repeat
        else
          set the nameIncrement to the nameIncrement + 1
        end if
      end repeat
    end if
  end tell
  return the targetName
end resolveConflicts

on processItem(SourceFile, newName, resultsFolder)
  try
    set the targetPath to ((resultsFolder as string) & newName) as string
    with timeout of 900 seconds
      do shell script "/Scripts/convert-docbook.sh ¥"" & POSIX path of SourceFile & "¥" ¥"" & POSIX path of targetPath & "¥""
    end timeout
  on error errorMessage
    tell application "Finder"
      activate
      display dialog errorMessage buttons {"Cancel"} default button 1 giving up after 120
    end tell
  end try
end processItem
この AppleScript をフォルダに関連付けて今回の作業は終了。

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 11, 2008

[Dolphin] J2SE 7.0 の closure で遊んでみた

先日構築した J2SE 7.0 EA で closure の動作環境で早速遊んでみた。

サンプルコード(0)

まずは引数を受け取って戻り値を返す closure。

public class Test2 {
  public Test2(){
    super();
  }

  public static void main(final String[] args) {
    int result = {int arg => arg * arg}.invoke(3);
    System.out.println(result);
  }
}
>java.bat Test2
9

サンプルコード(1)

次に、参照型の引数を受け取って、参照型の戻り値を返す closure。

public class Test3 {
  public Test3(){
    super();
  }

  public static void main(final String[] args) {
    Comparee c0 = new Comparee(0);
    Comparee c1 = new Comparee(1);

    Comparee result = {Comparee c0, Comparee c1 => 
                       c0.getValue() >= c1.getValue() ? c0 : c1}.invoke(c0, c1);
    System.out.println("" + result.getValue());
  }

  public static class Comparee {
    private final int value;

    public Comparee(final int value){
      super();
      this.value = value;
    }

    public int getValue(){
      return this.value;
    }
  }
}
>java.bat Test3
1

サンプルコード(2)

既存のインタフェース(Comparable)を暗黙で実装したとみなされる closure。 簡単な Comparable の実装は楽になるな。

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Test4 {

  public Test4(){
    super();
  }

  public static void main(final String[] args) {
    List<Comparee> list = new ArrayList<Comparee>();
    list.add(new Comparee(1));
    list.add(new Comparee(3));
    list.add(new Comparee(0));
    list.add(new Comparee(2));

    Comparator<Comparee> comparator = 
      {Comparee c0, Comparee c1 => c0.getValue() - c1.getValue()};

    System.out.println("" + list);

    Collections.sort(list, comparator);

    System.out.println("" + list);
  }

  public static class Comparee {
    private final int value;

    public Comparee(final int value){
      super();
      this.value = value;
    }

    public int getValue(){
      return this.value;
    }

    public String toString(){
      return "" + this.value;
    }
  }
}
>java.bat Test4
[1, 3, 0, 2]
[0, 1, 2, 3]

サンプルコード(3)

closure を引数で受け取るメソッド。

public class Test5 {

  public Test5(){
    super();
  }

  public static void main(final String[] args) {
    invoker({String message, int count => 
      for(int i = 0; i < count; i++){
        System.out.print("" + message);
      }
      System.out.println();
    });

    invoker({String message, int count => 
      for(int i = 0; i < count; i++){
        System.out.print("-" + message);
      }
      System.out.println();
    });
  }

  public static void invoker({String, int => void} invokee){
    invokee.invoke("*", 5);
  }
}
>java.bat Test5
*****
-*-*-*-*-*

サンプルコード(4)

closure を実装するクラス。

public class Test6 {

  public Test6(){
    super();
  }

  public static void main(final String[] args) {
    check(new MyChecker(), 5);
    check(new MyChecker(), -1);
  }

  public static void check(final {int => boolean} f, final int i) {
    System.out.println("" + f.invoke(i));
  }

  public static class MyChecker implements {int => boolean} {
    public MyChecker(){
      super();
    }

    public boolean invoke(final int i) {
      return i < 0;
    }
  }
}
>java.bat Test6
false
true

Posted in Dolphin | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 10, 2008

[Misc] Putty の鍵 (*.ppk) を OpenSSH 形式に変換する方法をメモ

Windows 時代は Putty を愛用していたが、Mac OS X に移行して Putty を使わなくなった。 手元には大量の ppk ファイルが orz。 Mac OS X の ssh でも使用出来るように OpenSSH 形式に変換しておいた。

変換方法

Putty に付属の PUTTYGEN.EXE で ppk を OpenSSH 形式に変換できる。 PUTTYGEN.EXE を起動して、ppk を読み込み、OpenSSH でエクスポートするだけ。
[PUTTYGEN.EXE(1)] [PUTTYGEN.EXE(2)]

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 09, 2008

[Dolphin] J2SE 7.0 EA で closure 環境を用意する。

そろそろ closure を実際に使用しておこうかと思い、JDK 7.0 EA をダウンロードして closure 環境を用意してみた。 現時点(2008/09/09)では JDK 単体では closure は利用できず、別途 closure ライブラリを用意する必要がある様だ。

Closures for the Java Programming Language (aka BGGA)
http://javac.info/
JSR Proposal: Closures for Java
http://www.javac.info/consensus-closures-jsr.html
JDK 7 Project
https://jdk7.dev.java.net/
Java Platform, Standard Edition 7 Binary Snapshot Releases
http://download.java.net/jdk7/binaries/

closure 環境の準備

まずは JDK 7.0 EA をダウンロードする。 今回使用したのは現時点で最新と思われる jdk-7-ea-bin-b34-windows-i586-28_aug_2008.exe。 closure ライブラリは javac.info から closures.tar.gz をダウンロードする。

>set JAVA_HOME=C:\_java\jdk\1.7.0-ea-28_aug_2008
>set PATH=%PATH%;%JAVA_HOME%\bin
>java -version
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b34)
Java HotSpot(TM) Client VM (build 14.0-b03, mixed mode, sharing)

>javac -version
javac 1.7.0-ea
JDK 7.0 EA 単体では closure は利用できないらしいが、とりあえず試してみる。
>md test
>cd test

>javac Test.java
Test.java:7: 式の開始が不正です。
    int value = { => 1 + 2 }.invoke();
                  ^
Test.java:7: 式の開始が不正です。
    int value = { => 1 + 2 }.invoke();
                   ^
Test.java:7: ';' がありません。
    int value = { => 1 + 2 }.invoke();
                            ^
エラー 3 個

>javac -source 7 -target 7 Test.java
Test.java:7: 式の開始が不正です。
    int value = { => 1 + 2 }.invoke();
                  ^
Test.java:7: 式の開始が不正です。
    int value = { => 1 + 2 }.invoke();
                   ^
Test.java:7: ';' がありません。
    int value = { => 1 + 2 }.invoke();
                            ^
エラー 3 個
やはり無理だった。
で、closure ライブラリを導入してみる。
>xcopy /S \closures-2008-08-11\* \_java\jdk\1.7.0-ea-28_aug_2008
\closures-2008-08-11\CHANGES
\closures-2008-08-11\DISTRIBUTION
C:\_java\jdk\1.7.0-ea-28_aug_2008\LICENSE を上書きしますか (Yes/No/All)? y
\closures-2008-08-11\LICENSE
\closures-2008-08-11\bin\java
\closures-2008-08-11\bin\java.bat
\closures-2008-08-11\bin\javac
\closures-2008-08-11\bin\javac.bat
\closures-2008-08-11\bin\javadoc
\closures-2008-08-11\bin\javadoc.bat
\closures-2008-08-11\lib\closures.jar
10 個のファイルをコピーしました
先程と同じテストコードを実行してみる。
>javac.bat Test.java

>java.bat Test
3

>
動いた。今回はここまで。

使用したテストコード

上で使用したテストコード(Test.java)はこれ。

public class Test{
  public Test(){
    super();
  }

  public static void main(final String[] args){
    int value = { => 1 + 2 }.invoke();
    System.out.println(value);
  }
}

Posted in Dolphin | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 08, 2008

[Apple] AppleScript から rsync を実行

rsync にはいつもお世話になっている。 コマンドラインで叩いてもさほど面倒というわけでもないのだけれど、ブログの更新の様に何度も繰り返して行う作業は自動化しておきたい。 今まではシェルスクリプトを利用していたのだけれど、何となく AppleScript 化してみた。

rsync.expect

rsync に AppleScript からパスワードを渡すために expect を使用する。 少々面倒だけれど、とりあえず expect で 汎用的な rsync 制御用の関数を用意しておく。 何かで使い回せるかもしれないし。 ・・・といって使い回した試しはないが。

#!/usr/bin/expect
proc Rsync {RsyncServer RsyncPort RemoteUser RemotePassword RemoteDirectory LocalDirectory} {
  set timeout 10;
  spawn rsync -av --port=$RsyncPort $LocalDirectory $RemoteUser@$RsyncServer:$RemoteDirectory
  expect {
   password: {send "$RemotePassword¥r";}
   timeout {puts stderr "rsync timeout."; return 1;}
  }
  expect {
    sent {return 0;}
    Permission {puts stderr "login failed."; return 2;}
  }
  return 0
}

set ARG0 [lindex $argv 0]
set ARG1 [lindex $argv 1]
set ARG2 [lindex $argv 2]
set ARG3 [lindex $argv 3]
set ARG4 [lindex $argv 4]
set ARG5 [lindex $argv 5]

set Result [Rsync $ARG0 $ARG1 $ARG2 $ARG3 $ARG4 $ARG5]
exit $Result

bloguploader.scpt

次に、rsync.expect を呼び出す AppleScript を作成する。 Password はスクリプト内には埋め込みたくないので、ダイアログで入力するようにしておいた。 このスクリプトはこのまま Automator で使用しても OK。

display dialog "Enter password: " default answer ""
set RsyncPassword to text returned of result

do shell script "/usr/bin/expect -f /Users/me/Documents/rsync.expect www.example.com 873 me " & RsyncPassword & " /home/me/blog /Users/me/Documents/Blog/"

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 07, 2008

[Linux] CentOS 5 に PostgreSQL をインストール

CentOS 5 に PostgreSQL をインストールしたときのメモ。 CentOS 5 にデフォルト状態で設定されている yum のリポジトリには 2008/09/07 現在 PostgreSQL 8.1.11 しか登録されていない。 今回は 8.1 ではなく 8.2 をインストールしたいので、8.2 をインストール出来るよう設定をしてみた。

RepoView: PostgreSQL PGDG Repository RPMs - Letter P
http://yum.pgsqlrpms.org/reporpms/repoview/letter_p.group.html
pgdg-centos - PostgreSQL 8.4.X PGDG RPMs for CentOS - Yum Repository Configuration
http://yum.pgsqlrpms.org/reporpms/repoview/pgdg-centos.html

CentOS 5 のデフォルト状態

CentOS 5 をクリーンインストールした直後はこんな感じ。

# yum search postgresql
postgresql-server.i386 : The programs needed to create and run a PostgreSQL server.
postgresql-docs.i386 : Extra documentation for PostgreSQL
perl-DBD-Pg.i386 : A PostgresSQL interface for perl
qt4-postgresql.i386 : PostgreSQL drivers for Qt's SQL classes
postgresql-test.i386 : The test suite distributed with PostgreSQL.
libdbi-dbd-pgsql.i386 : PostgreSQL plugin for libdbi
postgresql-devel.i386 : PostgreSQL development header files and libraries.
php-pdo.i386 : A database access abstraction module for PHP applications
freeradius-postgresql.i386 : postgresql bindings for freeradius
postgresql-contrib.i386 : Contributed source and binaries distributed with PostgreSQL
php-pgsql.i386 : A PostgreSQL database module for PHP.
qt-PostgreSQL.i386 : PostgreSQL drivers for Qt's SQL classes.
php-pgsql.i386 : A PostgreSQL database module for PHP.
postgresql-libs.i386 : The shared libraries required for any PostgreSQL clients.
postgresql-pl.i386 : The PL procedural languages for PostgreSQL.
postgresql-libs.i386 : The shared libraries required for any PostgreSQL clients.
rhdb-utils.i386 : Miscellaneous utilities for PostgreSQL - CentOS Edition.
mod_auth_pgsql.i386 : Basic authentication for the Apache web server using a PostgreSQL database.
unixODBC.i386 : A complete ODBC driver manager for Linux.
mono-data-postgresql.i386 : Postgresql database connectivity for Mono
postgresql-jdbc.i386 : JDBC driver for PostgreSQL
php-pdo.i386 : A database access abstraction module for PHP applications
postgresql.i386 : PostgreSQL client programs and libraries.
bind-sdb.i386 : The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server with database backends.
bind-sdb.i386 : The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server with database backends.
pdns-backend-postgresql.i386 : PostgreSQL backend for pdns
bind-sdb.i386 : The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server with database backends.
postgresql-python.i386 : Development module for Python code to access a PostgreSQL DB.
postgresql-odbc.i386 : PostgreSQL ODBC driver.
postgresql-tcl.i386 : A Tcl client library for PostgreSQL.

# yum install postgresql-server
Setting up Install Process
Parsing package install arguments
Resolving Dependencies
--> Running transaction check
---> Package postgresql-server.i386 0:8.1.11-1.el5_1.1 set to be updated
--> Processing Dependency: postgresql = 8.1.11-1.el5_1.1 for package: postgresql-server
--> Running transaction check
---> Package postgresql.i386 0:8.1.11-1.el5_1.1 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

=============================================================================
 Package                 Arch       Version          Repository        Size 
=============================================================================
Installing:
 postgresql-server       i386       8.1.11-1.el5_1.1  base              3.9 M
Installing for dependencies:
 postgresql              i386       8.1.11-1.el5_1.1  base              2.9 M

Transaction Summary
=============================================================================
Install      2 Package(s)         
Update       0 Package(s)         
Remove       0 Package(s)         

Total download size: 6.7 M
Is this ok [y/N]: N
Exiting on user Command
Complete!

yum の設定

yum に PostgreSQL のリポジトリを登録する。 今回は訳あって 8.3 ではなく 8.2 が必要なので、8.2 用のリポジトリを登録する。

# wget http://yum.pgsqlrpms.org/reporpms/8.2/pgdg-centos-8.2-4.noarch.rpm
--17:44:40--  http://yum.pgsqlrpms.org/reporpms/8.2/pgdg-centos-8.2-4.noarch.rpm

  (略)

17:44:40 (2.88 MB/s) - `pgdg-centos-8.2-4.noarch.rpm' saved [4311/4311]

# rpm -ivh ./pgdg-centos-8.2-4.noarch.rpm 
Preparing...                ########################################### [100%]
   1:pgdg-centos            ########################################### [100%]

PostgreSQL のインストール

リポジトリの登録が終わったので、早速 PostgreSQL 8.2 をインストールしてみる。

# yum search postgresql
pgdg82                    100% |=========================| 1.9 kB    00:00     
primary.sqlite.bz2        100% |=========================|  45 kB    00:00     
python-psycopg2-doc.i386 : Documentation for psycopg python PostgreSQL database adapter
slony1-docs.i386 : Documentation for Slony-I
python-psycopg2-doc.i386 : Documentation for psycopg python PostgreSQL database adapter
pgpool-II-debuginfo.i386 : Debug information for package pgpool-II
pgpool-II-devel.i386 : The  development files for pgpool-II
pgpool-debuginfo.i386 : Debug information for package pgpool
pgpool-II.i386 : Pgpool is a connection pooling/replication server for PostgreSQL
perl-DBD-Pg.i386 : A PostgresSQL interface for perl
postgresql-plpython.i386 : The Python procedural language for PostgreSQL
postgresql-jdbc.i386 : JDBC driver for PostgreSQL
postgresql-libs.i386 : The shared libraries required for any PostgreSQL clients.
postgresql-libs.i386 : The shared libraries required for any PostgreSQL clients.
dbi-link.noarch : Partial implementation of the SQL/MED portion of the SQL:2003 specification
postgresql-test.i386 : The test suite distributed with PostgreSQL.
skytools.i386 : PostgreSQL database management tools from Skype
libpqxx.i386 : C++ client API for PostgreSQL
pgsphere.i386 : R-Tree implementation using GiST for spherical objects
bind-sdb.i386 : The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server with database backends.
pdns-backend-postgresql.i386 : PostgreSQL backend for pdns
pgdg-redhat.noarch : PostgreSQL 8.2.X PGDG RPMs for RHEL - Yum Repository Configuration
postgresql-odbc.i386 : PostgreSQL ODBC driver
phpPgAdmin.noarch : Web-based PostgreSQL administration
postgresql-docs.i386 : Extra documentation for PostgreSQL
pgpool.i386 : Pgpool is a connection pooling/replication server for PostgreSQL
qt4-postgresql.i386 : PostgreSQL drivers for Qt's SQL classes
postgresql-pltcl.i386 : The Tcl procedural language for PostgreSQL
python-psycopg2.i386 : A PostgreSQL database adapter for Python
odbcng.i386 : PostgreSQL ODBCng driver
postgresql-libs.i386 : The shared libraries required for any PostgreSQL clients
postgresql-test.i386 : The test suite distributed with PostgreSQL
postgresql-python.i386 : Development module for Python code to access a PostgreSQL DB
postgresql-tcl-debuginfo.i386 : Debug information for package postgresql-tcl
php-pgsql.i386 : A PostgreSQL database module for PHP.
postgresql-plperl.i386 : The Perl procedural language for PostgreSQL
postgresql-tcl.i386 : Tcl client library for PostgreSQL
ptop.i386 : 'top' for PostgreSQL process
ip4r.i386 : IPv4 and IPv4 range index types for PostgreSQL
postgresql-contrib.i386 : Contributed source and binaries distributed with PostgreSQL
table_log.i386 : Log data changes in a PostgreSQL table
unixODBC.i386 : A complete ODBC driver manager for Linux.
postgis.i386 : Geographic Information Systems Extensions to PostgreSQL
python-psycopg2.i386 : A PostgreSQL database adapter for Python
pgfouine.noarch : PgFouine PostgreSQL log analyzer
postgresql-devel.i386 : PostgreSQL development header files and libraries.
postgresql-server.i386 : The programs needed to create and run a PostgreSQL server
postgresql-jdbc-debuginfo.i386 : Debug information for package postgresql-jdbc
postgresql-devel.i386 : PostgreSQL development header files and libraries
pgdg-centos.noarch : PostgreSQL 8.2.X PGDG RPMs for CentOS - Yum Repository Configuration
postgresql-odbc.i386 : PostgreSQL ODBC driver.
postgresql-tcl.i386 : A Tcl client library for PostgreSQL.
postgis.i386 : Geographic Information Systems Extensions to PostgreSQL
postgresql-odbc-debuginfo.i386 : Debug information for package postgresql-odbc
postgresql-python-debuginfo.i386 : Debug information for package postgresql-python
slony1-docs.i386 : Documentation for Slony-I
pgplsh.i386 : Sh shell procedural language handler for PostgreSQL
postgresql-contrib.i386 : Contributed source and binaries distributed with PostgreSQL
usda-r18.noarch : The USDA Food Database Sample for PostgreSQL
qt-PostgreSQL.i386 : PostgreSQL drivers for Qt's SQL classes.
php-pgsql.i386 : A PostgreSQL database module for PHP.
postgresql-debuginfo.i386 : Debug information for package postgresql
pgadmin3.i386 : Graphical client for PostgreSQL
rhdb-utils.i386 : Miscellaneous utilities for PostgreSQL - CentOS Edition.
mono-data-postgresql.i386 : Postgresql database connectivity for Mono
pgpool-II.i386 : Pgpool is a connection pooling/replication server for PostgreSQL
pgdg-centos.noarch : PostgreSQL 8.2.X PGDG RPMs for CentOS - Yum Repository Configuration
bind-sdb.i386 : The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server with database backends.
python-psycopg2-zope.i386 : Zope Database Adapter ZPsycopgDA
postgresql-server.i386 : The programs needed to create and run a PostgreSQL server.
plruby.i386 : PostgreSQL Ruby Procedural Language
slony1.i386 : A "master to multiple slaves" replication system with cascading and failover
libdbi-dbd-pgsql.i386 : PostgreSQL plugin for libdbi
php-pdo.i386 : A database access abstraction module for PHP applications
freeradius-postgresql.i386 : postgresql bindings for freeradius
postgresql-pl.i386 : The PL procedural languages for PostgreSQL.
postgresql-docs.i386 : Extra documentation for PostgreSQL
compat-postgresql-libs-debuginfo.i686 : Debug information for package compat-postgresql-libs
pagila.noarch : A sample database for PostgreSQL
slony1.i386 : A "master to multiple slaves" replication system with cascading and failover
python-psycopg2-zope.i386 : Zope Database Adapter ZPsycopgDA
mod_auth_pgsql.i386 : Basic authentication for the Apache web server using a PostgreSQL database.
pgpool-II-devel.i386 : The  development files for pgpool-II
postgresql-jdbc.i386 : JDBC driver for PostgreSQL
php-pdo.i386 : A database access abstraction module for PHP applications
postgresql.i386 : PostgreSQL client programs and libraries.
bind-sdb.i386 : The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server with database backends.
postgresql.i386 : PostgreSQL client programs and libraries
postgresql-python.i386 : Development module for Python code to access a PostgreSQL DB.
compat-postgresql-libs.i686 : PostgreSQL client programs and libraries
pgpool-II-debuginfo.i386 : Debug information for package pgpool-II

# yum install postgresql-server
Setting up Install Process
Parsing package install arguments
Resolving Dependencies
--> Running transaction check
---> Package postgresql-server.i386 0:8.2.9-1PGDG.rhel5 set to be updated
--> Processing Dependency: postgresql = 8.2.9 for package: postgresql-server
--> Processing Dependency: libpq.so.5 for package: postgresql-server
--> Running transaction check
---> Package postgresql-libs.i386 0:8.2.9-1PGDG.rhel5 set to be updated
--> Processing Dependency: libpq.so.4 for package: apr-util
---> Package postgresql.i386 0:8.2.9-1PGDG.rhel5 set to be updated
--> Running transaction check
---> Package compat-postgresql-libs.i686 0:4-1PGDG.rhel5 set to be updated
--> Finished Dependency Resolution

Dependencies Resolved

=============================================================================
 Package                 Arch       Version          Repository        Size 
=============================================================================
Installing:
 postgresql-server       i386       8.2.9-1PGDG.rhel5  pgdg82            4.0 M
Updating:
 postgresql-libs         i386       8.2.9-1PGDG.rhel5  pgdg82            196 k
Installing for dependencies:
 compat-postgresql-libs  i686       4-1PGDG.rhel5    pgdg82             63 k
 postgresql              i386       8.2.9-1PGDG.rhel5  pgdg82            1.6 M

Transaction Summary
=============================================================================
Install      3 Package(s)         
Update       1 Package(s)         
Remove       0 Package(s)         

Total download size: 5.9 M
Is this ok [y/N]: y
Downloading Packages:
(1/4): postgresql-server- 100% |=========================| 4.0 MB    00:12     
(2/4): postgresql-8.2.9-1 100% |=========================| 1.6 MB    00:02     
(3/4): compat-postgresql- 100% |=========================|  63 kB    00:00     
(4/4): postgresql-libs-8. 100% |=========================| 196 kB    00:00     
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Updating  : postgresql-libs              ######################### [1/5] 
  Installing: postgresql                   ######################### [2/5] 
  Installing: compat-postgresql-libs       ######################### [3/5] 
  Installing: postgresql-server            ######################### [4/5] 
  Cleanup   : postgresql-libs              ######################### [5/5] 

Installed: postgresql-server.i386 0:8.2.9-1PGDG.rhel5
Dependency Installed: compat-postgresql-libs.i686 0:4-1PGDG.rhel5 postgresql.i386 0:8.2.9-1PGDG.rhel5
Updated: postgresql-libs.i386 0:8.2.9-1PGDG.rhel5
Complete!
# psql --version
psql (PostgreSQL) 8.2.9
contains support for command-line editing
# 

Posted in Linux | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 04, 2008

[Misc] Google Chrome on Mac OS X のビルドにチャレンジ

とりあえず Windows XP Professional では Google Chrome が動作したので、次は Mac OS X で動かないか調べてみた。 現時点(2008/09/04)では、 Google Chrome のサイトでは Mac OS X 用のバイナリは公開されていない。 が、ドキュメントを見ていたら Mac OS X でのビルド方法が公開されていた。 というわけで、さっそくチャレンジ。

Chrome Developer Documentation - Build Instructions (Mac OS X)
http://dev.chromium.org/developers/how-tos/build-instructions-os-x

Google Chrome のソースコードを入手

まずは depot_tools をダウンロードして実行できる様にする。

$ tar zxvf ./depot_tools_mac.tar.gz
depot_tools/.svn/
depot_tools/.svn/text-base/
depot_tools/.svn/text-base/gcl.svn-base
depot_tools/.svn/text-base/gclient.svn-base
depot_tools/.svn/text-base/hammer.svn-base
depot_tools/.svn/text-base/README.svn-base
depot_tools/.svn/prop-base/
  (略)
$ export PATH=`pwd`/depot_tools:$PATH
次に、depot_tools 内にある gclient を使用して Chrome のソースコードをダウンロードする。
$ mkdir -p ./src/trunk
$ cd ./src/trunk/
$ gclient config http://src.chromium.org/svn/trunk/src
checking out latest depot_tools...
$ gclient sync

________ running 'svn checkout http://src.chromium.org/svn/trunk/src src' in '/chrome/src/trunk'
A    src/sdch
A    src/sdch/using_sdch.vsprops
A    src/sdch/open_vcdiff
A    src/sdch/open_vcdiff/depot
A    src/sdch/open_vcdiff/depot/opensource
A    src/sdch/open_vcdiff/depot/opensource/open-vcdiff
  (略)
$
Chrome のソースコードがダウンロードできたら、XCode を使用してビルドを行う。
$ xcodebuild -version
Component versions: DevToolsCore-921.0; DevToolsSupport-893.0
$ xcodebuild -project ./src/trunk/src/webkit/tools/test_shell/mac/TestShell.xcodeproj
2008-09-04 00:50:54.203 xcodebuild[22183:613] NOTE: Referenced project Skia was written by a newer Xcode version (45) -- temporarily downgrading it (without modifying project file)
2008-09-04 00:50:54.254 xcodebuild[22183:613] NOTE: Referenced project net was written by a newer Xcode version (45) -- temporarily downgrading it (without modifying project file)
  (略)
/chrome/src/trunk/src/webkit/build/Release/DerivedSources/v8/bindings/V8BarInfo.cpp:75: error: ‘v8’ has not been declared
/chrome/src/trunk/src/webkit/build/Release/DerivedSources/v8/bindings/V8BarInfo.cpp:75: error: expected constructor, destructor, or type conversion before ‘<’ token
/chrome/src/trunk/src/webkit/build/Release/DerivedSources/v8/bindings/V8BarInfo.cpp:82: error: ‘v8’ has not been declared
/chrome/src/trunk/src/webkit/build/Release/DerivedSources/v8/bindings/V8BarInfo.cpp:82: error: ‘char**’ is not a template
/chrome/src/trunk/src/webkit/build/Release/DerivedSources/v8/bindings/V8BarInfo.cpp:82: error: ‘v8’ has not been declared
/chrome/src/trunk/src/webkit/build/Release/DerivedSources/v8/bindings/V8BarInfo.cpp:82: error: ‘Value’ was not declared in this scope
/chrome/src/trunk/src/webkit/build/Release/DerivedSources/v8/bindings/V8BarInfo.cpp: In static member function ‘static bool WebCore::V8BarInfo::HasInstance(char**)’:
/chrome/src/trunk/src/webkit/build/Release/DerivedSources/v8/bindings/V8BarInfo.cpp:83: error: ‘GetRawTemplate’ was not declared in this scope
** BUILD FAILED **
$ 
ビルド失敗 orz コマンドラインではなく XCode の GUI からもビルドしてみたが、結果は同じ。 Chrome のソースコードを gclient でダウンロードしたものではなく、tar.gz で公開されているものにしてみたが、それでもだめ。

・・・で。

結局現時点では Mac OS X 版をビルドすることはできない様だ。 中の人がブログで Mac OS X 版の現状を説明していた。 モジュール単位ではビルドできるらしいが、全体のビルドは無理とのこと。 残念。 早く Mac OS X 版が出て欲しいものだ。

Google Mac Blog - Platforms and Priorities
http://googlemac.blogspot.com/2008/09/platforms-and-priorities.html
When it comes to Mac and Linux versions, this means that our goal is not to just "port" a Windows application to these other platforms--rather, our goal is to deliver Chromium's innovative, Google-style user interface without rough edges on any of them. Chromium's overall design has been multi-platform from the start, but we are also committed to getting the details right for users on each platform.

(略)

Right now, both are in the "pieces build and pass tests, but there's no Chromium application yet." While we're working hard and fast on catching up to the Windows version, we're not setting an artificial date for when they'll be ready--we simply can't predict enough to make a solid estimate, and we expect to learn a lot from the Windows public beta as well. On the plus side, since the project is now public, you'll be able to watch (and maybe even contribute to) the progress from week to week. As these versions stabilize, we will create official betas, much as we are now for the Windows version. While we can't give any dates yet, we'll keep everyone informed as we get closer.

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

[Misc] Google Chrome のタスクマネージャの Always on top を解除する方法

Google Chrome をぼーっと眺めていたら、タスクマネージャの Always on top を解除する方法を見つけた。 ・・・だから何だ、と言われても困るが。

編集するファイルは
C:\Documents and Settings\Administrator\Local Settings\Application Data\Google\Chrome\User Data\Local State

task_manager の always_on_top がデフォルトで "true" になっているので、"false" に変えて Google Chrome を再起動する。

{
   "task_manager": {
      "window_placement": {
         "always_on_top": true,
         "bottom": 599,
         "left": 452,
         "maximized": false,
         "right": 920,
         "top": 300
      }
   },
}

[AlwaysOnTopが解除できた]

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

[Misc] Google Chrome の User-Agent

Google Chrome の User-Agent を調べてみた。 2008/09/03 にダウンロードした Windows 用のバイナリでは以下の User-Agent が使用される。

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 03, 2008

[Misc] Google Chrome にチャレンジ

Google が Chrome という独自 Web ブラウザを公開した。 インストールしてみないことには始まらないので、とりあえずインストールしてみた。

Google Chrome
http://www.google.com/chrome/
Google Chrome - 機能
http://www.google.com/chrome/intl/ja/features.html

インストールの風景

[Chrome をダウンロード] [Chrome をインストール中]
[Chrome のインストール準備完了]

Google Chrome を使ってみた

[Chrome が起動した] [とりあえずここを表示できた]
[シークレットモード] [タスクマネージャ]

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 01, 2008

[Misc] web.xml を分割する方法

久しぶりに Servlet を書くことになった。 Servlet ベースで Web アプリケーションを書くと web.xml がすぐにカオスになってしまうのが難点。 Servlet Specification 2.4 では XMLSchema が導入されたので、DTD を使用していた Servlet Specification 2.3 以前に比べると web.xml を分割し易くなっている。 というわけで、混沌としてくる前に web.xml を分割していくことにした。

web.xml の分割方法

web.xml の分割は非常に簡単。 web.xml 用の特別な方法があるわけではなく、XML の実体参照を使用するだけ。

web.xml はこんな感じ。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app [
<!ENTITY function0 SYSTEM "web-function0.xml">
<!ENTITY function1 SYSTEM "web-function1.xml">
]>

<web-app xmlns="​http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="​http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="​http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"
	version="2.5">

	&function0;
	&function1;

</web-app>
web.xml 内で参照されている web-function0.xml はこんな感じ。 Servlet 2.3 までの <servlet> と <servlet-mapping> との順序の制約が無くなったので、web-funcion0.xml が読み易い。
<servlet>
	<servlet-name>jp.in_vitro.function0.FooServlet</servlet-name>
	<servlet-class>jp.in_vitro.function0.FooServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>jp.in_vitro.function0.FooServlet</servlet-name>
	<url-pattern>/function0/foo</url-pattern>
</servlet-mapping>

<servlet>
	<servlet-name>jp.in_vitro.function0.BarServlet</servlet-name>
	<servlet-class>jp.in_vitro.function0.BarServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>jp.in_vitro.function0.BarServlet</servlet-name>
	<url-pattern>/function0/bar</url-pattern>
</servlet-mapping>

それにしても <url-pattern> の表現能力の貧弱さは何とかならないものか。 今時 Servlet ベースの開発はつらい。

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Aug 28, 2008

[AS] Apache Tomcat Directory Traversal Vulnerability を再現してみる。

Apache Tomcat の Directory Traversal 脆弱性が報告されている。 報告だけではイマイチ分かりにくいので再現実験を行ってみた。

SecurityForcus - Apache Tomcat Directory Traversal Vulnerability
http://www.securityfocus.com/archive/1/archive/1/495318/100/0/threaded
CVE-2008-2938
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-2938

脆弱性の内容

SecurityForcus によると、

As Apache Security Team, this problem occurs because of JAVA side. If your context.xml or server.xml allows 'allowLinking'and 'URIencoding' as 'UTF-8', an attacker can obtain your important system files.(e.g. /etc/passwd)

Exploit
If your webroot directory has three depth(e.g /usr/local/wwwroot), An attacker can access arbitrary files as below. (Proof-of-concept)
http://www.target.com/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/foo/bar
とのこと。allowLinking が true で且つ URIEncoding が UTF-8 に設定されている Apache Tomcat(〜6.0.16) で再現するそうだ。

allowLinking と URIEncoding

allowLinking と URIEncoding は、Apache Tomcat のドキュメントによると

Apache Tomcat Configuration Reference - The HTTP Connector
http://tomcat.apache.org/tomcat-6.0-doc/config/http.html
URIEncoding
This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.
Apache Tomcat Configuration Reference - The Context Container
http://tomcat.apache.org/tomcat-6.0-doc/config/context.html
allowLinking
If the value of this flag is true, symlinks will be allowed inside the web application, pointing to resources outside the web application base path. If not specified, the default value of the flag is false.
NOTE: This flag MUST NOT be set to true on the Windows platform (or any other OS which does not have a case sensitive filesystem), as it will disable case sensitivity checks, allowing JSP source code disclosure, among other security problems.
というものだそうだ。

脆弱性の再現

Apache Tomcat 6.0.16 を使用して脆弱性の再現実験を行った。 手順は以下の通り。

  1. Apache Tomcat 6.0.16 をインストール
  2. $CATALINA_HOME/conf/server.xml を編集
  3. $CATALINA_HOME/conf/context.xml を編集
  4. Apache Tomcat 6.0.16 を起動
  5. Web ブラウザより Apache Tomcat 6.0.16 にアクセスし、脆弱性を再現
server.xml はこんな感じ
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" 
               URIEncoding="UTF-8" />
  </Service>
</Server>
context.xml はこんな感じ
$CATALINA_HOME/conf/context.xml
<?xml version='1.0' encoding='utf-8'?>
<Context allowLinking="true">
</Context>
Web ブラウザで http://localhost:8080/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd にアクセスしたところ、脆弱性が再現できた。 [脆弱性が再現できた]

もう少し調べてみる

allowLinking, URIEncodign がそれぞれ設定されていない場合はどうなるか試してみた。
[allowLinkngを設定しない場合] [URIEncodingを設定しない場合]
どちらも脆弱性は再現できなかった。

URIEncoding を UTF-16 にした場合はどうなるか試してみた。
[URIEncodingをUTF-16にした場合]
脆弱性は再現できなかった。

%c0%ae って何?

脆弱性が再現できたところで一つ気になるのは、%c0%ae が何者なのか、ということ。

System.out.println("" + URLDecoder.decode("%c0%ae", "UTF-8"));
.
まぁ想像通りの結果。 要するに、http://localhost:8080/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd は Apache Tomcat 内部で http://localhost:8080/../../../../etc/passwd と解釈されるわけだ。 で、何らかの原因で(「Java 側の問題」と書いてあるが、何だろう?)パスがチェックをすり抜けてファイルアクセスに使用されてしまう、ということだろう。

結論

とにかく Apache Tomcat を脆弱性が修正されている 6.0.18 以上にバージョンアップする必要がある。 急げ。急げ。

Posted in AS | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Aug 25, 2008

[Maven] Maven2 で Apache Tomcat の context.xml を WAR に追加する方法

Maven2 で Apache Tomcat の context.xml を WAR に追加する方法をメモ。 何故メモするかというと、現時点(2008/08/25)では普通に設定するだけでは動作しないから。
想定された通りの挙動であれば、pom.xml に

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <configuration>
          <containerConfigXML>src/main/webapp/META-INF/context.xml</containerConfigXML>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
と設定すれば src/main/webapp/META-INF/context.xml が WAR の META-INF/context.xml として格納される。
war:war
http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html#containerConfigXML
ところが、この containerConfigXML というオプション、maven-war-plugin のバグにより現時点では動作しない。
Option containerConfigXML doesn't work
http://jira.codehaus.org/browse/MWAR-120?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel
バグレポートによると既にこのバグは修正済みで、修正されたバージョンは 2.1-alpha-2 ということなので、maven-war-plugin を 2.1-alpha-2 にする必要がある。 maven-war-plugin 2.1-alpha-2 を使用するには pom.xml を下記の通り設定すれば良い。
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1-alpha-2</version>
        <configuration>
          <containerConfigXML>src/main/webapp/META-INF/context.xml</containerConfigXML>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
maven-war-plugin 2.1-alpha-2 のリリースノートはこちら。
[ANN] Maven War Plugin 2.1-alpha-2 Released
http://mail-archives.apache.org/mod_mbox/maven-announce/200808.mbox/%3Cadba96190808140822t6d87b6c2k9fa0d9ee444d5a9c@mail.gmail.com%3E

Posted in Maven | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Aug 24, 2008

[Maven] Maven2 で Test*.java をテストケースとして認識させない方法

Maven2 ではビルドの際に **/Test*.java、**/*Test.java、**/*TestCase.java をテストケースとして認識する。 Test*.java はテストケースとして使用したくないので、設定を変更してみた。

surefire:test
http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html#includes

設定の変更方法

pom.xml に以下を追加する。

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <includes>
            <include>**/*Test.java</include>
            <include>**/*TestCase.java</include>
          </includes>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Posted in Maven | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Aug 19, 2008

[Misc] HP System Management Homepage を CentOS 5.2 にインストールしてみた。

HP System Management Homepage: Installation Guide
http://docs.hp.com/en/438862-009/index.html
HP System Management Homepage for Linux (x86)
http://h20000.www2.hp.com/bizsupport/TechSupport/SoftwareDescription.jsp?lang=en&cc=us&prodTypeId=15351&prodSeriesId=1121486&prodNameId=3288144&swEnvOID=4006&swLang=8&mode=2&taskId=135&swItem=MTX-1b359c812b2e419ba234be0117
System Management Homepageによるハードウェア障害監視
http://www.thinkit.co.jp/free/article/0611/13/2/

HP SMH のインストール

HP のサイトから System Management Homepage for Linux (hpsmh-2.1.12-200.i386.rpm) をダウンロードする。 その後、RPM を使用して普通にインストール。 ・・・するが、やはり駄目。

# rpm --checksig ./hpsmh-2.1.12-200.i386.rpm 
./hpsmh-2.1.12-200.i386.rpm: sha1 md5 OK
# rpm -i --test ./hpsmh-2.1.12-200.i386.rpm 
# rpm -ivh ./hpsmh-2.1.12-200.i386.rpm 
Preparing...                ########################################### [100%]
This Red Hat Linux distribution is not supported.
error: %pre(hpsmh-2.1.12-200.i386) scriptlet failed, exit status 1
error:   install: %pre scriptlet failed (2), skipping hpsmh-2.1.12-200
#

ディストリビューションがサポートされていないということなので、ディストリビューションを詐称してみる。 今度は上手くいった。

# cp /etc/redhat-release /etc/redhat-release.original
# vi /etc/redhat-release
# diff /etc/redhat-release.original /etc/redhat-release
1c1
< CentOS release 5.2 (Final)
---
> Red Hat Enterprise Linux AS release 5
# rpm -ivh ./hpsmh-2.1.12-200.i386.rpm 
Preparing...                ########################################### [100%]
Creating hpsmh user and group...
   1:hpsmh                  ########################################### [100%]

**********************************************************
* System Management Homepage installed successfully with *
* default configuration values.   To change the default  *
* configuration values,  type the following command at   *
* the root prompt:                                       *
*                                                        *
* perl /usr/local/hp/hpSMHSetup.pl                       *
*                                                        *
**********************************************************


Stopping hpsmhd: 
Starting hpsmhd: 

hpsmhd: Could not determine the server's fully qualified domain name, using 10.1.31.33 for ServerName
[  OK  ]
# rm /etc/redhat-release
rm: remove regular file `/etc/redhat-release'? yes
# mv /etc/redhat-release.original /etc/redhat-release

HP SMH の設定

HP SMH の設定はインストール時に表示された通り以下のスクリプトで行う。

# perl /usr/local/hp/hpSMHSetup.pl

HP SMH にアクセス

Web ブラウザで http://localhost:2381/ にアクセスする。

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Jul 16, 2008

[Apple] Mac OS X で DNS キャッシュのクリア

/private/etc/hosts の変更内容がすぐに反映されない で Tiger での DNS キャッシュのクリア方法をメモしたが、Leopard ではコマンドが変更となったので追記。

Leopard(10.5)
$ dscacheutil -flushcache
Tiger(10.4)
$ sudo lookupd -flushcache

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Jul 03, 2008

[Misc] ratproxy にチャレンジ

ratproxy とは

ratproxy は Google がオープンソースで公開した Web アプリケーションの脆弱性をチェックする HTTP proxy。

A semi-automated, largely passive web application security audit tool, optimized for an accurate and sensitive detection, and automatic annotation, of potential problems and security-relevant design patterns based on the observation of existing, user-initiated traffic in complex web 2.0 environments.
Mac OS X でも動くということなので試してみた。
ratproxy
http://code.google.com/p/ratproxy/

ratproxy のインストール

Mac OS X 10.4 (Tiger) と 10.5 (Leopard) で試してみた。

$ tar zxvf ./ratproxy-1.51.tar.gz
$ cd ./ratproxy
$ make
cc ratproxy.c -o ratproxy  -Wall -O3 -Wno-pointer-sign -D_GNU_SOURCE http.c mime.c ssl.c -lcrypto -lssl

*** WARNING: flare-dist/flare bianry is not operational.
*** Please see flare-dist/README and update it for your OS.
$
というわけで、早速怒られた(といっても単なる警告だけれど)。 flare-dist/README を読めということなのでとりあえず見てみることに。

$ vi ./flare-dist/README
This is a Linux binary of Flare ActionScript decompiler. If instructed
to do so, ratproxy will invoke this tool to decompile SWF files on the
fly.

If you intend to run ratroxy on a different operating system, you may
need use the following binaries instead:

http://www.nowrap.de/download/flare06mac.tgz
ratproxy に同梱されている flare という SWF の逆コンパイラが Mac OS X 用ではないということらしい。 有り難いことに別途 Mac OS X 用のバイナリが用意されているらしいので、いそいそとダウンロード。 同梱の flare を Mac OS X 用のバイナリで上書きして、make をやり直してみる。

$ cd ..
$ tar zxvf ./flare06mac.tgz
$ cp ./flare06mac/* ./ratproxy/flare-dist/
$ cd ./ratproxy
$ make
cc ratproxy.c -o ratproxy  -Wall -O3 -Wno-pointer-sign -D_GNU_SOURCE http.c mime.c ssl.c -lcrypto -lssl

$ chmod 755 ./ratproxy
$ ./ratproxy
ratproxy version 1.51-beta by 
[!] WARNING: Running with no command-line config options specified. This is
    almost certainly not what you want, as most checks are disabled. Please
    consult the documentation or use --help for more information.

[*] Proxy configured successfully. Have fun, and please do not be evil.
[+] Accepting connections on port 8080/tcp (local only)...
^C
$
今度は警告も無くコンパイルが完了した。 とりあえず動かしてみたところ何事もなく動作した模様。

ratproxy で脆弱性をチェックしてみる

ratproxy が動くようになったところで、早速脆弱性をチェックしてみる。 まずは Web ブラウザの proxy 設定で localhost:8080 を proxy として登録する。 後は普通にチェックしたいサービスにアクセスするだけ。 すると下記の様なログが出力される。

$ ./ratproxy -lxtiscgjmXC
ratproxy version 1.51-beta by 

[!] WARNING: Running with no 'friendly' domains specified. Many cross-domain
    checks will not work. Please consult the documentation for advice.

[*] Proxy configured successfully. Have fun, and please do not be evil.
    WARNING: Disruptive tests enabled. use with care.
[+] Accepting connections on port 8080/tcp (local only)...
1|3|Risky Javascript code|innerHTML|200|31742|text/html|application/xhtml+xml|UTF-8|-|GET|
http://example.com:80/someservice/hoge|-|-|\r\n<?xml version=
1|1|Bad or no charset declared for renderable file|-|200|124136|application/x-javascript|a
pplication/x-javascript|-|-|GET|http://example.com:80/someservice/script/prototype.js|-|-|
1|1|Markup in dynamic Javascript|-|200|124136|application/x-javascript|application/x-javas
cript|-|-|GET|http://example.com:80/someservice/script/prototype.js|-|-|
1|1|Risky Javascript code|document.write|200|124136|application/x-javascript|application/x
-javascript|-|-|GET|http://example.com:80/someservice/common/js/prototype.js|-|-|
3|3|Inline PNG image|-|200|21640|image/png|image/png|-|-|GET|http://example.com:80/someser
vice/dummy.png|-|-|‰PNG\r\n\x1a\n
0|1|HTTP errors|-|404|209|text/html|text/html|iso-8859-1|-|GET|http://demo.beat.co.jp:80/f
avicon.ico|-|-|<!DOCTYPE HTML PUBLIC "
1|1|Bad or no charset declared for renderable file|-|200|1010|text/javascript|text/javascr
ipt|-|-|GET|http://example.com:80/someservice/scruot/selectbox.js|-|-|var 
0|3|Dynamic Javascript for direct inclusion|-|200|844|text/javascript|text/javascript|UTF-
8|-|GET|http://example.com:80/someservice/script/baselistdisplay.js|-|-|\r\nvar
0|7|GET query with no XSRF protection|-|200|11074|text/javascript|text/javascript|utf-8|-|
GET|http://www.google.com:80/uds/api?
1|7|File name in query parameters|uds.js|200|11074|text/javascript|text/javascript|utf-8|-
|GET|http://www.google.com:80/uds/api?file=uds.js
1|7|XSS candidates (script)|key|200|11074|text/javascript|text/javascript|utf-8|-|GET|http:
//www.google.com:80/uds/api?file=uds.js
2|3|MIME type set to text/plain|-|200|8847|text/plain|application/x-javascript|UTF-8|-|GET|
http://example.com:80/someservice/dosomething|-|-|[{"
2|3|MIME type mismatch on renderable file|-|200|8847|text/plain|application/x-javascript|UT
F-8|-|GET|http://example.com:80/someservice/dosomething|-|-|[{"
というわけで、少し遊んだだけで中々興味深い結果を得ることができた。 真面目に使えばそれなりの効果を得られそうだ。

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Jun 30, 2008

[Apple] GnuPG on Mac OS X メモ

Mac OS X に GnuGP を入れてみた。 MacPorts を使ってインストール出来るので至極簡単。

GnuPG のインストール

$ sudo port search gnupg
qca-gnupg                      devel/qca-gnupg 2.0.0-beta2  Qt Cryptographic Architecture - openssl plugin
gnupg                          mail/gnupg     1.4.7        GNU pretty-good-privacy package
gnupg12                        mail/gnupg12   1.2.7        GNU Privacy Guard
gnupg2                         mail/gnupg2    2.0.8        GNU pretty-good-privacy package
p5-gnupg-interface             perl/p5-gnupg-interface 0.33         Perl interface to GnuPG
py-gnupg                       python/py-gnupg 0.3.2        GnuPGInterface is a Python module to interface with GnuPG
py25-gnupg                     python/py25-gnupg 0.3.2        GnuPGInterface is a Python module to interface with GnuPG
$
$ sudo port install gnupg
--->  Fetching ncursesw
--->  Attempting to fetch ncurses-5.6.tar.gz from http://ftp.gnu.org/gnu/ncurses
--->  Verifying checksum(s) for ncursesw
--->  Extracting ncursesw
--->  Applying patches to ncursesw
--->  Configuring ncursesw

  (SNIP)

--->  Staging gnupg into destroot
--->  Installing gnupg 1.4.7_0
--->  Activating gnupg 1.4.7_0
--->  Cleaning gnupg
$

GnuPG の動作確認

$ gpg --version
gpg (GnuPG) 1.4.7
Copyright (C) 2006 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.
$

GnuPG を使って復号化

$ gpg -d ./dummy.gpg > ./dummy
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
gpg: WARNING: message was not integrity protected
$

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Jun 23, 2008

[Apple] Cyberduck メモ

[Cyberduck]

Cyberduck は Mac OS X で動作する FTP, SFTP クライアント。SSH の公開鍵認証に対応している。 今までは Fugu を使用していたのだけれど、 残念なことに Fugu は公開鍵認証ができない。 公開鍵認証が必要になったので、今回 Fugu から Cyberduck に乗り換えてみた。

Cyberduck is an open source FTP, SFTP, WebDAV and Amazon S3 browser licenced under the GPL with an easy to use interface, integration with external editors and support for many Mac OS X system technologies such as Spotlight, Bonjour, QuickLook and the Keychain.
Cyberduck
http://cyberduck.ch/

Posted in Apple | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Jun 19, 2008

[Library] QR コードクラスライブラリ for Java にチャレンジ

QR コードクラスライブラリ for Java とは

QR コードクラスライブラリ for Java は、文字列から QR コードのデータを作成する Java 用のライブラリ。 ライブラリに文字列を渡すと boolean[][] の配列を返してくれる。 良く見かける QR コードの画像は boolean[][] から自前で作成する。

QR コードクラスライブラリ for Java
http://www.swetake.com/qr/java/qr_java.html

QR コードクラスライブラリ for Java で QR コード画像を作成してみる。

とりあえず ↓ の情報だけは一通り目を通すと良い。

QR コードクラスライブラリ for Java - API Document
http://www.swetake.com/qr/java/docs/index.html
QR Code.com - バージョンの決定
http://www.denso-wave.com/qrcode/vertable1.html
QR Code.com - コード領域の確定
http://www.denso-wave.com/qrcode/qrgene4.html

作成した画像をテストするには ↓ のツールを使用すると便利。

Psytec - QR Code Editor
http://www.psytec.co.jp/docomo.html

サンプルコード

// QRコードクラスライブラリ for Java の準備。
Qrcode qrcodeLogic = new Qrcode();
qrcodeLogic.setQrcodeEncodeMode('*');
qrcodeLogic.setQrcodeErrorCorrect('M');
qrcodeLogic.setQrcodeVersion(7);

// QR コードデータを作成。
byte[] targetBytes = target.getBytes();
boolean[][] qrcodeData = qrcodeLogic.calQrcode(targetBytes);

// QR コード画像用の BufferedImage を準備。
//   周りに 4cell 分のマージンを用意する。
BufferedImage image = new BufferedImage(size.getCellSize()
        * (qrcodeData[0].length + 8), size.getCellSize()
        * (qrcodeData[0].length + 8), BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();
g.setColor(QRCODE_IMAGE_BACKGROUNDCOLOR);
g.fillRect(0, 0, image.getWidth(), image.getHeight());

// QR コードデータを画像に変換。
for (int i = 0; i < qrcodeData.length; i++) {
    for (int j = 0; j < qrcodeData[i].length; j++) {
        boolean cellFilled = qrcodeData[i][j];
        Color cellColor = cellFilled ? QRCODE_IMAGE_FOREGROUNDCOLOR
                : QRCODE_IMAGE_BACKGROUNDCOLOR;
        g.setColor(cellColor);
        g.fillRect(size.getCellSize() * (i + 4), size.getCellSize()
                * (j + 4), size.getCellSize(), size.getCellSize());
    }
}
g.dispose();

Posted in Library | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Mar 10, 2008

[Misc] AIPO にチャレンジ

AIPO とは

AIPO は日本初のオープンソースグループウェア。 Java で構築されており、Apache Turbine, Portlet などをベースとしている。 面白そうなので試しに動かしてみた。

AIPO
http://aipostyle.com/

AIPO のインストール

以降の情報は aipo4000ja_linux.tar.gz を前提とする。 AIPO の公式サイトに記載のある Linux 動作環境は CentOS 5.0 のみだったが、 CentOS の環境を用意するのが面倒だったので Debian Sarge 上で動かしている。 当然付属のインストーラは動作しなかったが、手動でインストールしたら動いた(様に見える)。 まぁ、Java だしね。

AIPO アーカイブの解凍

# tar zxvf ./aipo4000ja_linux.tar.gz
aipo/backup/
aipo/backup/postgresql/
aipo/backup/postgresql/empty_dump/
 :
aipo/src/webapps/ROOT/error/404.html
aipo/src/webapps/ROOT/index.html
aipo/src/webapps/ROOT/WEB-INF/web.xml
# mv ./aipo ./aipo4000ja_linux
# mv ./aipo4000ja_linux /usr/local/
# cd /usr/local/aipo/src/
# ln -s ./aipo4000ja_linux ./aipo
# tar zxvf ./jakarta-tomcat-5.0.28.tar.gz 
jakarta-tomcat-5.0.28/bin/catalina.sh
jakarta-tomcat-5.0.28/bin/digest.sh
jakarta-tomcat-5.0.28/bin/setclasspath.sh
 :
jakarta-tomcat-5.0.28/webapps/webdav/index.html
jakarta-tomcat-5.0.28/webapps/webdav/tomcat-power.gif
jakarta-tomcat-5.0.28/webapps/webdav/tomcat.gif
# mv ./jakarta-tomcat-5.0.28 /usr/local/aipo
# cd /usr/local/aipo
# ln -s ./jakarta-tomcat-5.0.28 ./tomcat

AIPO を Apache Tomcat にディプロイ

# rm -rf /usr/local/aipo/tomcat/webapps/*
# cp -rf /usr/local/aipo/src/webapps/* /usr/local/aipo/tomcat/webapps
# cp /usr/local/aipo/src/tools.jar /usr/local/aipo/tomcat/common/lib
# cp /usr/local/aipo/src/postgresql-8.1/postgresql-8.1-407.jdbc3.jar /usr/local/aipo/tomcat/common/lib

PostgreSQL の準備

AIPO が DBMS に接続する際に使用するアカウント情報と DB 名を調べる。 /usr/local/aipo/tomcat/webapps/aipo/WEB-INF/conf/postgres/Org001DomainNode.driver.xml に記載があった。

DB 名
org001
ユーザ名
aipo_postgres
パスワード
aipo
ちなみに、付属のインストーラを使用してインストールを行う場合は、これらの値は適宜変更される。

# createuser aipo_postgres -P -U postgres
Enter password for new role: 
Enter it again: 
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) y
Shall the new role be allowed to create more new roles? (y/n) n
CREATE ROLE
# createdb -E UTF-8 org001 -U aipo_postgres
CREATE DATABASE
# psql -U aipo_postgres -d org001 -f /usr/local/aipo/backup/postgresql/sample_dump/aipo_db_sql.dump 
SET
SET
SET
GRANT
psql:../../backup/postgresql/sample_dump/aipo_db_sql.dump:2781: WARNING:  no privileges were granted
GRANT
# cp -rf /usr/local/aipo/backup/postgresql/sample_dump/psml /usr/local/aipo/tomcat/webapps/aipo/WEB-INF
# cp -rf /usr/local/aipo/backup/postgresql/sample_dump/files /usr/local/aipo/tomcat/webapps/aipo/WEB-INF
# cp -rf /usr/local/aipo/backup/postgresql/sample_dump/mail /usr/local/aipo/tomcat/webapps/aipo/WEB-INF

Apache Tomcat の起動

# export JAVA_HOME=/opt/jdk1.5.0_12
# cd /usr/local/aipo/tomcat/bin
# ./startup.sh 
Using CATALINA_BASE:   /usr/local/aipo/tomcat
Using CATALINA_HOME:   /usr/local/aipo/tomcat
Using CATALINA_TMPDIR: /usr/local/aipo/tomcat/temp
Using JAVA_HOME:       /opt/jdk1.5.0_12/

動作確認

http://localhost:8080/aipo/ にアクセスすると AIPO のトップページが表示される。 デフォルトのユーザが 3 人表示され、それぞれパスワード無しでログインできる。

[AIPO TOP] [AIPO HOME]

Posted in Misc | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Feb 28, 2008

[SNS] OpenSocial JavaScript API にチャレンジ(5)

Orkut が管理している情報を外部サーバへ引き渡す

今回は Orkut の管理している情報(Orkut のユーザID)を外部サーバに引き渡してみた。

remoteservice.xml

Orkut へのディプロイ方法は前回と同じ。

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Remote Service">
    <Require feature="opensocial-0.7"/>
    <Require feature="settitle"/>
    <Require feature="views"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
<script>
// <!--
function getElement (id) {
  if (document.getElementById){
    return document.getElementById(id);
  } else if (document.all) {
    return document.all[id];
  } else if (document.layers) {
    return document.layers[id];
  } else {
    return null;
  }
}

function loadData() {
  var request = opensocial.newDataRequest();
  request.add(request.newFetchPersonRequest('OWNER'), 'owner');
  request.send(onLoadData);
}

function onLoadData(data) {
  // get owner info
  var owner = data.get('owner').getData();
  var ownerId = owner.getId();
  var ownerDisplayName = owner.getDisplayName();
  
  var s = "<dl>";
  s += "<dt>id</dt><dd>" + ownerId + "</dd>";
  s += "<dt>name</dt><dd>" + ownerDisplayName + "</dd>";
  s += "</dl>";

  getElement('owner').innerHTML = s;

  getElement('childframe').src = "http://www.in-vitro.jp/blog/entries/SNS/20080228_01/"
                                 + ownerId + ".html";
}
gadgets.util.registerOnLoadHandler(loadData);
loadData();
// -->
</script>
      <body>
        My local profile:<br />
        <div id="owner"></div><br />
        <br />
        My remote profile:<br />
        <iframe id="childframe"/><br />
      </body>
    ]]>
  </Content>
</Module>

[Orkut のユーザID].html

remoteservice.xml で指定した場所に設置。例) http://www.in-vitro.jp/blog/entries/SNS/20080228_01/[OrkutのユーザID].html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
  これはリモートサーバにあるプロフィール情報です。
</body>
</html>

実行結果

[remote service]
外部サーバに Orkut の管理している情報を引き渡すことができた。

Posted in SNS | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Feb 27, 2008

[SNS] OpenSocial JavaScript API にチャレンジ(4)

外部サーバへの XMLHttpRequest アクセス

前回 iframe を使用して外部サーバにある HTML を表示できることが確認できたので、 今回は XMLHttpRequest を使用して外部サーバにアクセスしてみる。

remoteaccess.xml

Orkut へのディプロイ方法は前回と同じ。

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Remote Access">
    <Require feature="opensocial-0.7"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
      <body>
        <iframe src="http://www.in-vitro.jp/blog/entries/SNS/20080227_01/child.html"/>
      </body>
    ]]>
  </Content>
</Module>

child.html

remoteaccess.xml で指定した場所に設置。例) http://www.in-vitro.jp/blog/entries/SNS/20080227_01/child.html

<body>
<script type="text/javascript">
// <!--
var dataUrl = "/blog/entries/SNS/20080227_01/data.xml";

function start() {
  fetchData();
}

function fetchData() {
  var request = prepareHttpRequest();
  request.open("GET" , dataUrl , true);
  request.onreadystatechange = function() { 
    if (request.readyState == 4 && request.status == 200) { 
      var response  = request.responseXML;
      var messages = response.getElementsByTagName('message');
      var s = "<ul>";
      for(i = 0; i < messages.length; i++) {
        s += "<li>" + messages[i].firstChild.nodeValue + "</li>";
      }
      s += "</ul>";
      document.getElementById('main').innerHTML = s;
    }
  }
  request.setRequestHeader("Content-Type" , "text/xml");
  request.send(null);
}

function prepareHttpRequest(){
  if(window.ActiveXObject){
    try {
      return new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        return new ActiveXObject("Microsoft.XMLHTTP");
      } catch (ex) {
          return null;
      }
    }
  } else if(window.XMLHttpRequest){
    return new XMLHttpRequest();
  } else {
    return null;
  }
}

start();
// -->
  </script>

  <div id="main"></div>
</body>

data.xml

child.html 内の JavaScript で指定した場所に設置。例) http://www.in-vitro.jp/blog/entries/SNS/20080227_01/data.xml

<?xml version="1.0" encoding="UTF-8" ?>
<data>
  <message>こんにちは。</message>
  <message>お元気ですか?</message>
  <message>私ですか?</message>
  <message>いえいえ、そんなに元気じゃないですよ。</message>
</data>

実行結果

[remote access]
外部サーバに XMLHttpRequest でアクセスして XML を取得し、表示することができた。

Posted in SNS | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Feb 26, 2008

[SNS] OpenSocial JavaScript API にチャレンジ(3)

iframe を使用した外部サーバ HTML の表示

今回は JavaScript API から離れて、アプリケーションから外部サーバの HTML を表示してみる。

usingiframe.xml

Orkut へのディプロイ方法は前回と同じ。

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Using iframe">
    <Require feature="opensocial-0.7"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
      <iframe src="http://www.in-vitro.jp/blog/entries/SNS/20080226_01/child.html"/>
    ]]>
  </Content>
</Module>

child.html

usingiframe.xml 内の iframe で指定した場所に設置する。例) http://www.in-vitro.jp/blog/entries/SNS/20080226_01/child.html

<div>
  This is child html.<br />
</div>

実行結果

[using iframe]
IFrame から外部サーバにある HTML を取得して表示することができた。

Posted in SNS | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Feb 25, 2008

[SNS] OpenSocial JavaScript API にチャレンジ(2)

Friends データへのアクセス

今回もチュートリアルに沿って遊んでみる。 友人データを API 経由で取得して一覧表示する。 ちなみに、チュートリアルのコードは Orkut sandbox (OpenSocial API ver.0.7) では動作しなかった。

OpenSocial Tutorial
http://code.google.com/apis/opensocial/articles/tutorial/tutorial-0.7.html
API Reference - opensocial
http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.html
API Refenrece - opensocial.DataRequest
http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.DataRequest.html
API Refenrece - opensocial.DataRequest.PeopleRequestFields
http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.DataRequest.PeopleRequestFields.html
API Reference - opensocial.Person
http://code.google.com/apis/opensocial/docs/0.7/reference/opensocial.Person.html

listfriends.xml

Orkut へのディプロイ方法は前回と同じ。

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="List Friends">
    <Require feature="opensocial-0.7"/>
    <Require feature="settitle"/>
    <Require feature="views"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
<script>
// <!--
function getElement (id) {
  if (document.getElementById){
    return document.getElementById(id);
  } else if (document.all) {
    return document.all[id];
  } else if (document.layers) {
    return document.layers[id];
  } else {
    return null;
  }
}

function loadData() {
  // prepare request
  var request = opensocial.newDataRequest();

  // prepare required details
  var required = new Array();
  required[0] = opensocial.Person.Field.ID;
  required[1] = opensocial.Person.Field.NAME;
  required[2] = opensocial.Person.Field.THUMBNAIL_URL;
  required[3] = opensocial.Person.Field.PROFILE_URL;

  // prepare parameters
  var parameters = {};
  parameters[opensocial.DataRequest.PeopleRequestFields.MAX] = 1000;
  parameters[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = required;

  // send request
  request.add(request.newFetchPeopleRequest('OWNER_FRIENDS', parameters), 'friends');
  request.send(onLoadData);
}

function onLoadData(data) {
  // get all friends data
  var friends = data.get('friends').getData().asArray();

  // create html snippet
  var s = "<ul>";
  for (var i=0; i<friends.length; i++) {
    var person = friends[i];
    var id = person.getId();
    var name = person.getField(opensocial.Person.Field.NAME);
    var firstname = name.getField(opensocial.Name.Field.GIVEN_NAME);
    var lastname = name.getField(opensocial.Name.Field.FAMILY_NAME);
    var displayname = person.getDisplayName();
    var picUrl = person.getField(opensocial.Person.Field.THUMBNAIL_URL);
    var profileUrl = person.getField(opensocial.Person.Field.PROFILE_URL);

    s += "<li>";
    s += "<a href='" + profileUrl + "'>" + displayname + "</a>";
    s += "</li>";
  }
  s += "</ul>";

  // display all friends
  getElement("friends").innerHTML = s;
}

// registerOnLoadHandler だけだとスタートしない Web ブラウザがある。何故??
gadgets.util.registerOnLoadHandler(loadData);
loadData();
// -->
</script>
<body>
<div id="friends"></div>
</body>
    ]]>
  </Content>
</Module>

実行結果

[remote access]
Orkut から JavaScript API 経由で友人リストを取得することができた。

Posted in SNS | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Feb 23, 2008

[SNS] OpenSocial JavaScript API にチャレンジ

OpenSocial とは

OpenSocial は SNS の共通公開 API の JavaScript 版。 MySpace, FriendStar, Orkut, Hi5 など海外の大手 SNS が対 Facebook で始めた規格。 Google が音頭を取っている。 mixi も対応を表明しているが、実際に使えるようになるのはいつになるのだろう。

JavaScript API を使うとアプリケーションを SNS にディプロイ出来るようになる。 Orkut が開発者用の sandbox 環境を用意してくれているらしいので、とりあえず試してみた。

OpenSocial
http://code.google.com/apis/opensocial/
Getting Started Guide
http://code.google.com/apis/opensocial/gettingstarted.html

Orkut sandbox へのアクセス権取得

とりあえず Orkut へアクセスして、Orkut のアカウントを登録する。 その後で、その Orkut アカウントで sandbox へのアクセスを申請する。 詳細はリンク先を参照のこと。

Orkut
http://www.orkut.com/
Orkut Developer Home
http://code.google.com/apis/orkut/

Hello, OpenSocial!

チュートリアルがあったので、とりあえずはチュートリアル通り Hello World から。

OpenSocial Tutorial
http://code.google.com/apis/opensocial/articles/tutorial/tutorial-0.7.html

helloworld.xml

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Hello World!">
    <Require feature="opensocial-0.7" />
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
      Hello, world!
    ]]>
  </Content>
</Module>

helloworld.xml の設置

リモートから HTTP アクセスが可能な適当な場所に helloworld.xml を設置する。

例) http://www.in-vitro.jp/blog/entries/SNS/20080223_01/helloworld.xml

Orkut sandbox への登録

[orkut(1)] [orkut(2)]
[orkut(3)] [orkut(4)]
[orkut(5)]

Posted in SNS | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |