ホーム   »  2006年04月
Archive | 2006年04月

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

PostgreSQL 運用メモ

◆ VACUUM の実行

PostgreSQL ドキュメント定常的なデータベース保守作業の俺様要約

  • PostgreSQL はレコードが更新/削除されても物理削除は行わない
  • これは VACUUM で行うので定期的な実行が必要
  • 更新頻度の高いテーブルほど頻繁に VACUUM のすること
  • 普通の VACUUMVACUUM FULL の 2 種類がある
  • 普通の VACUUM は使われていない領域に再利用可能なマークを付ける
  • 普通の VACUUM は不要領域がファイルの最後でない限りファイル縮小は行わない
  • 普通の VACUUM は他のトランザクションにほとんど影響しない
  • VACUUM FULL は不要領域の占有領域を削除しファイルを縮小する
  • VACUUM FULL は他のトランザクションに与える影響も甚大
  • 一般的には1日1回普通の VACUUM をしておけばよい
  • 全レコードを削除する場合は TRANCATE を使えば VACUUM する必要がない
  • トランザクション ID は 32 ビットで周回する
  • トランザクション ID が周回が発生するとデータ損失が起きる
  • 7.2 以降は 10 億トランザクション発行する前に VACUUM が必要
  • 残りトランザクション数が1000万を下回ると警告が出る
  • 残りトランザクション数が100万を下回ると発行が出来なくなる

俺様の理解

  • Java の Gabage Collection で例えるなら普通の VACUUM = Mark & Swept、VACUUM FULL = Compact 、Windows で例えるなら VACUUM FULL = デフラグ
  • 定期処理は1日1回普通の VACUUM だけで十分 (VACUUM FULL はディスク容量を見ながらの不定期で良い?)

◆ バックアップとリストア

PostgreSQL ドキュメントバックアップとリストアの俺様要約

  • pg_dump は運用中の実行が可能
  • pg_dump はテーブル構成や全レコードを SQL で出力する
  • 出力した SQL を psql に流し込むと再構築が可能
  • ユーザ等、クラスタまとめてバックアップしたい場合は pg_dumpall を使用
  • ファイルが大きくなる場合はパイプで圧縮すなり分割するなり
  • 単純なファイルコピーによるバックアップは postgreSQL の完全停止が必要 (全切断だけではNG)
  • ポイントインタイムリカバリ (PITR) という JFS やロールフォーワードのような障害復旧機構がある
  • RITR は WAL ファイルにログ (ジャーナル) を記録している
  • WAL ファイルを累積的に保管するだけで任意の時点でのスナップショットが再現できる
  • WAL ファイルをバックアップ機で再生すればホットスタンバイを実現できる

俺様の理解

  • 小規模システムなら pg_dump の定期バックアップで十分
  • pg_dump の定期バックアップが現実的でない大規模システムは WAL ファイルで

JCE で簡単暗号化

JDK 1.4 から Java Cryptography Extension (JCE) がコアライブラリに追加されている。これにより Java で DES や AES を使った共有鍵 (秘密鍵) 方式の暗号・復号が気軽に扱えるようになった。

// 暗号化するテキストをバイナリ化
String clearText = "This is secret text.";
byte[] binary = clearText.getBytes("UTF-8");

// 暗号化のキー
byte[] key = ("password").getBytes("UTF-8");

// 暗号化の実行
SecretKeySpec k = new SecretKeySpec(key, "DES");
Cipher c = Cipher.getInstance("DES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] encrypted = c.doFinal(binary);
 

キー (バイナリ) から SecretKeySpec を作成し、Cipher で暗号化を行う。キーは復号化するときにも使うので、乱数とか日付とか不確定なものは NG。また、使用できるキーのビット長はアルゴリズムに依存してるので注意。

上記のサンプルコードから元のバイナリに戻すには以下の通り。Cipher#init() に指定するモードが異なるだけである。

// 暗号化で使用したキー
byte[] key = ("password").getBytes("UTF-8");

// 復号化の実行
SecretKeySpec k = new SecretKeySpec(key, "DES");
Cipher c = Cipher.getInstance("DES");
c.init(Cipher.DECRYPT_MODE, k);
byte[] binary = c.doFinal(encrypted);

// 元の文字列を復元
String clearText = new String(binary, "UTF-8");

暗号化・復号化ともにバイナリからバイナリへの変換となる。文字列を暗号化する場合は、いったん getBytes() でバイナリ化してやる必要があるのだが、実行環境の文字エンコーディングの影響を受けないように "UTF-8" 固定にしておくのが無難。

より強固な暗号を使いたい場合は上記サンプルを元にアルゴリズムを変更してキーのビット幅増やせば良い。

FC2 モブログとセキュリティ

モブログとは、携帯から自分のブログに書き込みが出来る機能。正式名称なのか特定ブログシステムでの呼称か知らないが、ここ FC2 でも blog@fc2.*** 宛てにメールを送るだけでブログに公開される。街で変なものを見かけた場合は素早く写真を撮り、熱が冷めないうちにその場で更新できるのでかなり便利だ。

宛先のメールアドレスは固定となっている。管理画面で 「モブログ用のメールアドレス」 なるものを入力し、そのアドレスから届いたメールは全て自分のブログに掲載されるシステムらしい。

ふと、複数のユーザが同じメールアドレスを登録したらどうなるかという疑問が湧いた。これってセキュリティ上問題があるんじゃないだろうか。ざっとこんな結果が予想される。

  1. そもそも 「このアドレスは別の人に使われています」 とか出て登録できない
  2. どのブログにも掲載されない → 「掲載できません」 等の応答あり/なし
  3. 先または後に登録したアドレスに掲載される
  4. 両方に掲載される

携帯のメールアドレスを知っている悪意的な第三者 (友達とかそんな類) が居た場合は上記のどれも問題があるのではないだろう。

送信者が意図していないブログに掲載されるという意味で 3 と 4 は明らかにセキュリティ違反、というかバグだろう。また 1 と 2 に関しても他人の悪意的な行為で自分の機能が阻害される事になる。どう転んでも問題があるようだ。

この時点でまだ試していないので、オチ無しだったら済まない…

続きを読む

ミイラ取りがミイラ

海に落ちた車をクレーンで引き上げている様子。

クレーン車、到着!

がんばればんがれ!

上がった!

ぬおぉぉぉぉぉぉぉぉぉぉ!!!

あちゃ~

親分登場

余裕で引き上げ

よいしょ、よいしょ

うりゃ~

なんて、結構前にネットで見かけた笑いネタ。

 

だが時が経つにつれ、いつの間にやら一コマ加えられて流布するようになった。

アイヤ~!

ほ、本物か? 何かオチ狙い臭いし、コラ臭いし、だいたい最初見た時はなかったし… 奥の赤いセダンは 2 台目が到着してからは黒のワンボックスに変わってたはず。白いボードも 2 台目が来てからはいなくなってる。

ニセモノだとは思うが、何かもやもやするので Photoshop で弄ってみた。ちょっとした拡縮と平行移動で位置あわせするだけでこんなんなった。

うーん、どう見ても 5 枚目の合成です。本当にありがとうございました。

ネットで探してみたら結構検証されてるのね。こちらのサイト

http://kotonoha.main.jp/2005/02/04crane.html

では事細かに事の背景を調査されているようでした。

メール送信時に件名と本文を自動挿入

HTML の <a> タグを使用して、メールを送信する際に件名 (Subject) と本文を自動挿入する事が出来る。テンプレートの目的で使用しているのをしばしば見かけることがある。

<a href="mailto:your-address@domain?subject=件名&body=本文">メール</a>

<a href="mailto:reg@domain?subject=ID845727506992&body=このまま編集しないで送信すれば登録が完了します。">登録メール</a>

登録を完了するには以下のリンクからメールを送信してください。
登録メール (実在しないアドレスなので本当に送信しないように / このサイトが EUC なんで多分化けますが)

互換性についてなのだが、元々は Netscape Navigator の拡張機能であり RFC によって標準化されているものではない。しかし、かなり昔からあった小技なので (たしか 1998 年頃に買った本には既に載ってたような気がする) そこそこの対応は期待しても良いだろう。

メジャーどころの現行バージョンは対応済みなのでシェア比で見れば相当高いだろう (まぁそれでも未対応ブラウザ/メーラー向けの配慮があるに越したことはない)。手元で確認出来たものと、公式サイトにサポート情報が載ってるものをリストアップしてみた。

  • Mozilla Thunderbird
  • Microsoft Outlook (Outlook Express)
  • Lotus Notes
  • Becky!
  • DoCoMo (i-mode)
  • au (ezweb)
  • Tu-Ka (ezweb)

日本語を扱う場合に URL エンコードが必須かかどうかもちょっとずつ違うようだ。

システム開発では、受信時に処理を振り分ける目的でこの機能を検討しているかもしれない。そういう用途ならメールアドレスのほうに ID を埋め込んでしまった方がクライアント側の互換性は心配する必要がないし、意図しない変更 (何せ Subject や本文だし) のリスクは少なくなる。

<a href="reg845727506992@domain">登録完了</a>

メールサーバ側では reg~ から始まるアドレス宛てのメールを特定のプログラムに渡すよう設定するだけで済む。ただしこれには qmail や postfix のような拡張アドレスに対応した MTA が必要になる。sendmail で構築した既存のシステムを変更しないで対応するのは、残念ながら無理なようだ。

メール受信でプログラムを起動

Unix では ~/.forward/etc/aliases を使用して、メールの受信をトリガーにプログラムを起動することが出来る。

Unix の .forward ファイルは受信したメールを別のアドレスに転送するために使われることが多いのだが、パイプを使用してメールの内容をプログラムに渡すこともできる。記述方法は超簡単、| の後に実行権限のあるファイルを指定するだけ。もちろんシェルスクリプトでも C で作ったバイナリでもかまわない。

| myprogram 

.forward は個人管理のファイルなので、自分が受信したメールを加工処理して別アドレスに転送するような場合によく使用される。例えば vacation を使えば不在通知を自動応答する事も出来る。

一方、/etc/aliases はメールボックスのエイリアスを記述するためのファイルだ。こちらのファイルでも同様にパイプを使用して受信メールをプログラムに渡すことが出来る。

support: |/usr/company/replyandstore.sh 

これを利用して、受信と同時に機械的な応答メールを返し、サポート依頼データベースに保管するといったような使い方が出来る。

.forward, aliases どちらのファイルでも、起動されたプログラムは標準入力 (C の stdin, C++cin, Java の System.in) からメールの内容を読み出すことが出来る。まぁ、後は焼くなり煮るなり、至って普通のパイプ処理である。

こんなことが自由に出来てた古きよき時代もあった…

続きを読む

JAI 1.0_01 image/bmp MIME-Type のバグ

JAI をインストールした後に ImageIO.getReaderMIMETypes() で MIME-Type と照らし合わせて処理してみたのだが、どうも image/bmp の形式だけ意図した動きにならないようだ。

ImageIO がサポートしている MIME-Type に image/bmp が含まれていない動きになってしまうのだ。だがその文字列配列をコンソールに出力するとちゃんと image/bmp と表示される。ImageIO.getImageReadersByMIMEType("image/bmp") は有効な要素を一つも返してくれない。だが ImageIO.read() はちゃんと Windows Bitmap も読み込めるというおかしな現象だ。

アレコレ試行錯誤の末、どうも getReaderMIMETypes() が返す文字列に変な空白が入っているのに気付いた。うーん、バグっぽい… ということで BugParade で検索したら、何とこんなことになっていたのだ。

In BMPImageReaderSpi class you have MIME types defined as follows:
private static String mimeTypes[] = {
    "image/bmp, image/x-bmp, image/x-windows-bmp"
};

should it be:
private static String mimeTypes[] = {
    "image/bmp", "image/x-bmp, "image/x-windows-bmp"
}

   。 。
  / /  シポーン
( Д )

見ての通り、文字列配列にすべきところを 1 つのリテラルにしてしまっていたのだ (私が気付いた空白は各要素とコンマの間の空白だった)。こりゃ "image/bmp" とじゃ一致しないはずだわ…

BugParade では一応 JAI 1.1β で FIX という事になっている。手元で試したところ 1.0 では発生しない。つまり 1.0_01 固有の問題ということだ。

これは単に MIME-Type に関連する部分のみで、Windows Bitmap 画像の読み込み/書き込みは問題なくできるようだ。ImageIO + JAI で MIME-Type と絡めて扱う場合はちょっと注意が必要。

ImageIO で JAI を使う

JDK 1.4 から導入された Image I/O のおかげで Java から各種フォーマットの画像を簡単に読み書き出来るようになった。

// 画像の読み込み
File file = new File("photo.jpg");

BufferedImage img = ImageIO.read(file);

// 画像の書き込み
file = new File("photo.png");
ImageIO.write(img, "PNG", file);
 

標準でサポートされているフォーマットは、JDK 1.4 で GIF (読み込みのみ), JPEG, PNG、JDK 1.5 では加えて Windows (OS/2) Bitmap, Wireless Bitmap が追加されているようだ。どのような形式をサポートしているかは以下のコードで確認できる。

String[] format = ImageIO.getReaderFormatNames();
System.out.print("R: ");
for(int i=0; i<format.length; i++){
        if(i != 0)      System.out.print(", ");
        System.out.print(format[i]);
}
System.out.println();

format = ImageIO.getWriterFormatNames();
System.out.print("W: ");
for(int i=0; i<format.length; i++){
        if(i != 0)      System.out.print(", ");
        System.out.print(format[i]);
}
System.out.println();
 

上記を JDK 1.4 で実行すると:

C:>"c:\Program Files\j2sdk1.4.2_09\bin\java" IIOSupported
R: jpeg, gif, png, JPG, jpg, JPEG
W: jpeg, JPG, png, jpg, PNG, JPEG
 

また JDK 1.5 の場合は以下のような出力になる。

C:>"c:\Program Files\jdk1.5.0_05\bin\java" IIOSupported
R: BMP, bmp, jpeg, wbmp, gif, png, JPG, jpg, WBMP, JPEG
W: BMP, jpeg, bmp, wbmp, JPG, png, jpg, PNG, JPEG, WBMP
 

JDK 1.6 ではこれに加えて、Unisys の LZW 特許が切れた GIF の書き込みをサポートしている。

これだけサポートされていれば大抵の場合は十分なのだが、TIFF など特定フォーマットのサポートが必須なアプリケーションや、画像変換のようにサポートフォーマットの豊富さがユーザビリティに直結する類のアプリケーションもあるだろう。

そこで Java Advanced Imaging (JAI) を使って Image I/O のサポートフォーマットを増やしてみよう。

続きを読む

Ajax で Blog 更新日付を表示

前からやろうと思ってたオレサマ・サイト Blog 更新日付の自動表示にやっと対応した。 Ajax を使用して JavaScript から RSS を読み込み、最新記事の日付を表示させている。IE6 と Firefox 1.x で動作確認済み。詳しくは HTML ソース参照。

とはいえ実は大事な部分をごまかしている。セキュリティ制限のため JavaScript からは Blog を運営しているサイトと直接通信できない。こればかりは仕方が無いので、自宅のサーバで毎時 0 分に各 Blog の RSS を取得してオレサマ・サイトにアップロードしている。あればあったで何かと便利な自宅サーバである。

構造的には URL の先が動的な XML を生成するサーブレットなどでも良いから、何かとネタに使えそうな小技である。とはいえ strict data typing のない言語でアレコレ DOM をインスペクトするのはサンダルで屋久島を縦走するに等しい。項目を細分化して送信する必要があるなら、ぶっちゃけ対象要素の ID と innerHTML の値を XML にしてサーバから落とす ─ つまり Ajax を単なるバイパス機能として使用するくらいが勢いが良いだろう。

06.06.09 追記
知り合いからの障害報告で 8日→0日、9日→1日、8月→0月、9月→1月、になってしまうバグを修正。parseInt() に渡す数字の頭が 0 から始まっていると ("08" とか)  8 進数表現と解釈されるのをすっかり忘れてました。

Mozilla の disable-output-escaping

どうやら Mozilla 系 (Firefox, Netscape) のブラウザは <xsl:value-of>disable-output-escaping 属性を無視するらしい。

XML に記述されている &< などの文字は XSL の出力方法に適切な形式でエスケープされるのだが、この属性を "yes" に設定することでこの動作を解除する事が出来る。つまり XML に埋め込んだ HTML タグがそのまま利くようになるわけだ。

<?xml version="1.0"?>
<?xml-stylesheet href="style.xsl" type="text/xsl"?>
<search-engine><![CDATA[
    <a href="http://www.google.com">Google</a>
]]></search-engine>

上記のような XML に対して:

<xsl:value-of select="/search-engine" disable-output-escaping="yes" />

という記述は Google へのリンクを生成する (もし no にすれば <a href=... という文字がそのまま画面に表示される)。

ほとんどの XSL 対応ブラウザがこの挙動を踏襲しているにもかかわらず、Mozilla は no にした場合と同じ動作になる。しかも Mozilla 開発者によれば W3C 仕様のもにゃもにゃに準拠しているのでバグではない、将来的にも対応する予定も無い、解釈の違いだ、との事だ。

何じゃそりゃ。W3C の仕様にこの属性はちゃんと盛り込まれている。出力結果に非 Valid HTML が混ざるのに現行の設計が対応しておらず、2 重になってるパーサの実行コストにも跳ねるのですぐには対応できない、手を入れたくないというのが実際の本音のようだ。

とりあえず、この問題は JavaScript の力を借りて何とか回避することはできた。

続きを読む

QuickTime の環境破壊

Windows の自動更新が働いたので 2 週間ぶりくらいに ThinkPad を再起動した。なぜだかコマンドプロンプトの java の挙動がおかしくなっている。

C:\>java Hoge
Exception in thread "main" java.lang.NoClassDefFoundError: Hoge
 

何だか知らないけどカレントディレクトリのクラスファイルを認識しなくなってるようだ。とりあえず CLASSPATH を表示してみる。

C:\>echo %CLASSPATH%
C:\Program Files\Java\jre1.5.0_05\lib\ext\QTJava.zip
 

オオー!! これが噂の QuickTime のクラスパス破壊かー!

QuickTime のインストーラは勝手に環境変数 CLASSPATH を自分のライブラリに書き換えてしまう。そのため、デフォルト状態でカレントディレクトリを参照していたのがある日突然参照されなくなるように見えるのだ。一見 Java とは何の関係も無さそうな QuickTime / iTune などのインストールで発生するので、初心者プログラマやシステムのデプロイヤーがハマるのだ。

ところで最近 QuickTime なんてインストールしたっけか?? QuickTime も iTune もインストールしたのはかなり前だし、とはいえ 「この○○をアプレットから使用できるようにしますか?」 なんてメッセージを最近見た覚えもあるし。うーん、QuickTime の自動更新だろうか… ライセンス購入したのにひどい仕打ちだ orz

Ajax 云々

最近よく耳にするようになった Ajax (Asynchronous JavaScript and XML)。ブラウザを画面遷移させないで表示内容を入れ替える ─ 要は JavaScript が裏でこっそり通信しますよ、という技法だ (技術ではないな)。Google Maps での地図スクロールだとか、Google Suggest でのキーワード候補表示などを見ると画面の切り替えなしで実現出来ているのが分かる。

入力と結果表示がシームレスに繋がるので使い勝手は格段に向上するわけだが、いかんせんベースの技術が JavaScript である。業務アプリケーションのような特性のシステムであまり凝ったことをするなら、ポータビリティ、対障害性、メンテナンス性などの面でのデメリットの方が大きいだろう (さすがに 「全画面 Ajax で」 ってのは意味が無いのでないだろうが)。

通信結果の XML を参照して条件分岐したり、値を個別のセルに表示したりもできるのだが、JavaScript でそれをやり始めると設計が発散してしまうのは想像に難くない。システム開発で使うなら、画面内の特定領域 (<div> 要素で囲んだ部分) をサーバから取り出した HTML で丸ごと置き換える、といった単純な利用にとどめるのが良いだろう (6 年前にアプレットで似たようなデモ作った記憶が蘇る)。

使い所はどこだろうか? 裏で通信、ということは表の目的が別にあるわけで、つまりオプション機能とかツール、入力補助と言った用途に向いている。画面入力中に裏で新着のお知らせを確認、なんて技だな (クライアントプル技術なのでサーバからのイベント通知は不可)。 Yahoo! 翻訳などがやってるようなポーリング用途は転送量を増やさない意味でも良いかもしれない。

まぁそんな Web 開発向けの Tip 的な小技なのだが、どうも Google 先生が使ってるってんでキーワード付けて焚き付けようって感じが否めない。きっと 「ま た か!」 と思ったエンジニアも多いだろう (だいたい Ajax って名前付けた Jesse James Garrett 氏自体 Google と関係ないし)。

2000 年頃の IT バブル期じゃないんだから、こういう情報キーワード先行な仕掛け方はもうとっくに飽きられてるのにまだ気づいてないのかね。こと最近のは既存の技術・手法・文化にアリガタイ名前付けただけの粗悪品が多いし (少なくとも以前は理論、集大成、改良、あるいは新しい切り口などが付属してた)。「Web2.0」 なんてのはネーミングがいかにも過ぎて笑える。

ブラウザで簡易 HTML 編集

ここ fc2 ブログもそうなのだが、最近ブラウザで簡易 HTML エディタが機能しているのを目にする機会が増えた。文字の編集だけなら以下のような属性指定だけで簡単に出来るのだ。

<div contenteditable="true">
ここは編集可能。<b>強調</b><i>イタリック</i>
</div>
 

contenteditable 属性は Internet Explorer 5.5 以降でサポートされている。この実行結果は以下の通り。

ここは編集可能。強調イタリック

Internet Explorer だけでなく Firefox もサポートしたい場合は designMode 属性を使えば良い。こちらはページ全体が編集対象になるので、編集領域は iframe として使用する。見た感じ IE 限定なら contenteditable の方が楽そう。

ただ標準で用意されているのは純粋な文字編集機能だけなので、強調・斜体・フォント変更・サイズ変更・リンク・画像貼り付けなど、一通りの編集に対応するなら JavaScript でかなりの作りこみが必要だ。

これで HTML エディタ作ったらとんでもなく大変だろうと思っていたのだが、世の中には根性ある人も居るものだな。世界は広い。

System Integration

まね

Java + PostgreSQL で BLOB を扱う その 3

さらに続きである。これで完結である (ことを願う…)。

まずは観測から。

何とかなりそう! ヽ(´ー`)ノ

PostgreSQL で大きなバイナリを扱うには、今まで試した BYTEA 型を使用するほかに OID 型を使用する方法がある。BYTEA 型がバイナリそのものをテーブルに格納するのに対し、OID 型はオブジェクトの ID のみを格納し、実体のバイナリはどこか別のところに保存される (PostgreSQL の場合はシステムカタログのどこかに入るらしい)。

元々 BLOB がロケーション ID やオフセット、長さなどを使って巨大なバイナリを扱うための手段だということを考えれば、むしろこの OID 型を BLOB と呼ぶ方が自然だ (ちなみに商用データベースの方は実体をテーブルスペース外の別ファイルにするか VARBINARY と同様にテーブル内に入れるかなど、きめ細かな構成を選択できるが)。

PostgreSQL の JDBC ドキュメントを参照すると、Java で OID 型を扱うには "LargeObject API" なるものを使わなければならいように見えるが、実は JDBC の java.sql.Blob と互換性のある方法で取り扱えるようになっているようだ。正にこっちが PostgreSQL 的 BLOB なのである。

ネットを検索してみる限り、BYTEA 型を扱うサンプルはいくつか見つかるものの、OID 型を java.sql.Blob で扱う Java チュートリアルはほとんど無いようだ (これが日本語初か?)。なので今回はチュートリアルっぽくまとめてみる。例によってコード簡略化のためリソースのクローズや変数宣言等は省略。

続きを読む

Java + PostgreSQL で BLOB を扱う その 2

出た! (;´ー`)y─┛~~

前回、InputStream を使って巨大データを BYTEA 型カラムに格納出来たわけだが、今度は保存した内容を取り出すタイミングで再び OutOfMemoryError が姿を現した。

なんだかすごーく嫌な予感がするのだが… とりあえず 8.1 ドライバのソースでも見てみるか。

public InputStream getBinaryStream(int columnIndex)
    throws SQLException
{
    // ...
    if (connection.haveMinimumCompatibleVersion("7.2")){
        // Version 7.2 supports BinaryStream for
        //
all PG bytea type As the spec/javadoc for
        // this method indicate this is to be used for
        //large binary values (i.e. LONGVARBINARY)
        // PG doesn't have a separate long binary
        // datatype, but with toast the bytea datatype is
        // capable of handling very large values.  Thus
        // the implementation ends up calling getBytes()
        // since there is no current way to stream the
        // value from the server
        byte b[] = getBytes(columnIndex);
        if (b != null)
            return new ByteArrayInputStream(b);
    } else {
        // 7.1 以前の場合
    }
    return null;
}
 

. .: : : : : : : : :: :::: :: :: : :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    . . : : : :: : : :: : ::: :: : :::: :: ::: ::: ::::::::::::::::::::::::::::::::::::::
   . . .... ..: : :: :: ::: :::::: :::::::::::: : :::::::::::::::::::::::::::::::::::::::::::::
        Λ_Λ . . . .: : : ::: : :: ::::::::: :::::::::::::::::::::::::::::
       /:彡ミ゛ヽ;)ー、 . . .: : : :::::: :::::::::::::::::::::::::::::::::
      / :::/:: ヽ、ヽ、 ::i . .:: :.: ::: . :::::::::::::::::::::::::::::::::::::::
      / :::/;;:   ヽ ヽ ::l . :. :. .:: : :: :: :::::::: : ::::::::::::::::::
 ̄ ̄ ̄(_,ノ  ̄ ̄ ̄ヽ、_ノ ̄ ̄ ̄ ̄

 

続きを読む

Java+PostgreSQLでBLOBを扱う その1

PostgreSQL 7.4.11 (JDBC 3 Driver 7.4.215) の BYTEA (BLOB) 型カラムにファイルの内容を放り込もうと思ったのだが、ファイルサイズが数十MB になると例外が発生してしまうようだ。

java.lang.OutOfMemoryError: Java heap space

例外が起きなくてもディスクスワップが多発しているようだし、ひょっとしてファイルの全バイナリから巨大な SQL でも組み立てているのだろうか? 今回はそこらへんをちょっと突っ込んで調べてみようと思う。

続きを読む

FilreFoxのXSL対応

Mozilla Firefox 1.0.7 (Linux) で XML + XSL を表示させてみたところ

Error loading stylesheet: (null)

http://servername/stylesheet.xsl

などと表示されてしまった。一応 XSLT の処理までは行っているようだが、はてさて原因メッセージが null じゃどこが悪いのか皆目見当も付かず…

試行錯誤の末、どうやら XSL ファイルに対してサーバが返す Content-Typetext/xml にしてやらなきゃダメらしいということまで分かった。text/xsl でもダメなのである。なんとも息苦しい挙動である。

しかもサーバ側で XSLT 処理して HTML 落としてた時と比べて微妙に挙動が違うじゃん! 今までは JavaScript で documet.all("id") とやっていても JavaScript コンソールに警告が出る程度だったのに、何か全面的に禁止になってるみたいだ。うーん、変更の本質でない部分で挙動変わると何か先行き不安だす (´・ω・`)

緯度・経度・測地系

私が使用している au の携帯電話には GPS 機能が付いている。現在地を確認しながら目的地までリアルタイムにナビゲーションしたり (ez ナビウォーク)、カメラで撮った写真に現在位置を記録できるので便利だ。

旅先で何気ない風景や変な看板なんかを撮るので、以前は 「この写真撮ったのどこだっけ?」 という事がよくあった。初めて車で遠出した時に撮った風車や、瀬戸内の島々が並ぶ風景の場所などは未だに分からない。そんなわけで、位置をメモする代わりに携帯で写真を撮って GPS 情報を付加して保存するようになったわけだ。

最近 GPS に関するネタを調べる機会があったのでちょっと書いてみる。

続きを読む

mutable な Date クラス

java.util.Date クラスが immutable じゃないのは、Calendar の登場した 1.1 以降では設計ミスだね。HashtableMap インターフェースのように、以前との互換性を保ちつつより抽象化されたインターフェースを乗っけてほしかった。

意図しない変更を避けるために日時データは基本的に long 型で持ちまわるようにしているが、DateFormat で文字列化する時に毎回 Date インスタンスを作成するオーバーヘッドが気にかかる。気にかかると言っても気持ち悪い程度の問題ではあるが。

Profile
Takami Torao
Takami Torao
C/C++ 使いだった 1996年、運命の Java と出会い現在に至る。のらアーキテクト。
Yah, this is image so I don't wanna eat spam, sorry!
Search

Google
MOYO Laboratory
Web

カテゴリー
最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
ブロとも申請フォーム
RSSフィード
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。