fc2ブログ
ホーム   »  2006年03月
Archive | 2006年03月

オカルト開発現場

オーパーツ (OOPARTS) とは、「場違いな工芸品」という意味。それらが発見された場所や時代とはまったくそぐわないと考えられる物品を指し、英語の Out Of Place Artifacts の頭文字をとったものである。日本語では「時代錯誤遺物」と意訳されることもある。

quoted from Wikipedia

開発現場は時にオカルトである。この業界の人間なら誰しも一度は 「こびとさん (俗称)」 の事例を耳にしたことがあるだろう。助けられた人や嫌われてる人、住み家と思しきサーバの裏にこっそり供物を置く人や、さらにはモカの過剰摂取で実際に目撃したという人まで出る始末。こびとさんとは関係なくても、ルーターの出初式にオフダをかかさない人、開発機に〆縄張る人など、情報化社会の仕事人とはいえ、やはりそこは人間である。

最近、オーパーツという単語を目にする機会があったので調べてみた。何でも古代遺跡から出てきたトンデモ遺物 ─ マヤのパレンケ遺跡で見つかったロケットの設計図だとか、白亜紀の地層から出た靴で歩いたような足跡の化石だとか、まるで手塚治虫の三つ目がとおるを彷彿とさせるようなそんな類のものである。

開発の現場でも、意外なところで場違いかつ用途不明なモノを発見をすることがしばしばある。知らない人が残していったツールであったり、あるいはもはや実行環境すらない 20 年前の COBOL ソースであったり。その手のものはまとめてオーパーツと呼んで良いだろう。それに OOParts って何かオブジェクト指向チックじゃない。

大きなプロジェクトだと、終盤に差し掛かった頃に全ソースを 「?」 「なぜか」 「かも」 「多分」 「絶対」 「はず」 などで検索してみると大変興味深いものが見られるだろう。もちろんそれを全部消せなんて野暮なことは言わないで、黙って一つ一つ丹念にコードを確認出来る人間だけがこびとさんになる資格を持つのである。

CVSでディレクトリごと追加

CVS ってディレクトリごとまとめて追加って出来ないんだよな…。Linux でディレクトリ hoge をまとめて追加したい場合は bash の力を借りてこんな感じ。

cvs add `find hoge -type d -print`
cvs add `find hoge -type f -print | grep -v /CVS/`
cvs commit
hoge

最初に hoge 以下の全ディレクトリをガツンと追加。次に全ファイルをごっそり追加。ただし CVS の管理ディレクトリに入ってる奴は除いて。最後に commit でめでたくディレクトリ全部コミットされましたと。

JMFとファイル拡張子

ローカルのファイルを JMF で再生する場合、どうやらファイルの拡張子を見てメディアのタイプを判断しているようだ。

JMF を試すための簡単なコードは以下のような感じ (あらかじめ Sun のサイトから JMF をダウンロードしておき jmf.jar にクラスパスを通しておく)。Player を生成しコントローラーと一緒に JFrame などに埋め込んで表示する。

URL url = new File("QuickTimeやMPEGなどのパス").toURL();
JFrame frame = new JFrame("Instant JMF Player");
final Player player = Manager.createRealizedPlayer(url);
frame.getContentPane().add(
    player.getVisualComponent(), BorderLayout.CENTER);
frame.getContentPane().add(
    player.getControlPaneComponent(), BorderLayout.SOUTH);
frame.setDefaultCloseOperation(
    WndowConstants.DISPOSE_ON_CLOSE);
frame.pack();
// 閉じたときに止めないと音声だけ鳴り続ける
frame.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e){
        player.stop();
        player.close();
    }
});
// 表示前に開始/終了しておくと
// 初期状態で最初のフレームを表示しておける
player.start();
player.stop();
frame.show();

続きを読む

XSLT逐次処理

XSL を使って XML を処理するケースについて。

XML をストリームで生成する場合、XSLT が逐次処理を行ってくれると省コストで高パフォーマンスが得られて重宝するだろう。つまり XSLT が  FilterWriter がごとく機能し、そこに XML を出力して行けば下層ストリームに変換結果が出力されるという設計だ。

だがコアライブラリの javax.xml.transform ライブラリはそうなっていない。DOM または入力ストリームのみを Source として受け付けており、これは最初に完成された XML ありき、という事を意味している。

果たして逐次処理は出来ないのか? という事で XML 生成処理を別スレッド化し、ストリームを PipedReader/PipedWriter で繋げて XSLT を実行してみたところ、やはり XML の生成が完了するまで XSLT の出力は開始しないようだ。

そもそも逐次処理は可能なのだろうか? あれこれ考えてみた。XSL の XPath には特定の位置の要素を指したり、count() などで要素数を得るような処理が記述できる。そういった処理が含まれる以上、結局どこかで完成した DOM が必要ということになり、変換処理を逐次で行うのは現実的でないという事なのだろう。

やはりデータ量が多くなればなるほど XML は不利っぷりはひどいな。残念無念。

fc2blog セッション保存時間切れの対処方法

ここ FC2 ブログでは記事の編集中にしばしばセッションタイムアウトにぶち当たることがある。いざ、渾身の長文を保存しようとして

セッション保存時間が切れました。再度ログインしてください。
m9(^Д^)プギャー!!

などと出た日にゃ、ディスプレイにヘッドバッドかましてそのまま窓から飛び降りたいくらいの焦燥感を喰らうわけだ。

先日その対処法に気づいたのでここに記しておく。某掲示板にも書いてみたが多分初出だろう。

続きを読む

黄金比

黄金比黄金比、と呼ばれる比率がある。矩形の最も美しいと言われる縦横比のことだ。まぁ詳細は Wikipedia でも参照してもらうとして、古くは古代ギリシャ時代から 「神の比率」 と呼ばれて来た比率である。

ここからフィボナッチ数列の話などを始める気はないのだが ─ 最近ふと気づいたのだが、コンピュータのディスプレイやデジカメの写真、携帯電話の画面などに慣れてしまったため、黄金比が黄金比に見えなくなってしまっている。このまま時代が進めば VGA 比が黄金比と呼ばれる時代が来るのかもしれない…

ちなみに、同じ紙の比率でも A4、B5 といった紙の大きさを表す規格は、紙を半分に切っても縦横比が変わらないという極めて機能的な理由で 1:√2 (1:1.41) の比率になっている。

XSLT 出力ビューアー

Microsoft Internet Explorer は 5.0 から XML + XSL での表示をサポートしている。動的なデータは XML で、静的なレイアウトは XSL でと分離が出来るので、サーバの処理コストと通信負荷を押さえたりクライアントアプリケーション (非ブラウザ) との統合を図ったり、また、いざという時はサーバ側で XSLT を動かしたりも出来るので個人的には気に入っている構成なのだ。

ただ、この方式は XSLT プロセッサがブラウザの中に隠蔽されているので開発時には少々不便でもある。XML + XSL でどういう HTML が生成されたか、開発者は見ることが出来ないわけだ。そこでこのプラグインの紹介。

上記は IE 上での XSLT 処理結果を表示出来るようにするプラグインだ。ダウンロードしたファイルを実行して全てのブラウザを開きなおせば、コンテキストメニュー (ページ上での右クリック) に 「Validate XML」 と 「View XSL Output」 の 2 つのメニューが追加されているだろう。これで名前の通り XML の検証と XSL 出力表示を行うことが出来る。

※うまく行かないときはインストールディレクトリの 2 つの *.inf ファイルを右クリックしてインストールする。

始祖鳥

Archaeopteryx
əkiáptərIks | à:kiɔp-]
アーケオプテリクス
始祖鳥

RFC1864: The Content-MD5 Header Field

HTTP の Content-MD5 ヘッダを調べるついでに、RFC 1864 The Content-MD5 Header Field の翻訳を完了。4ページ程度だったのでわりかしちゃっちゃと終わった。128bit 固定の Base64 符号化で OK と。

ちょっともったいぶった感のある文章でした。RFC 読んでると結構書いてる人の癖が見えるね。何人かが書いてる場合は同じドキュメントでもセクションによって癖が違ったりとか。

ZIPファイル内の非UTF-8ファイル名

Java では java.util.zip パッケージのクラスを使用して簡単に ZIP ファイルを扱うことが出来る。例えば以下のようなコードで ZIP ファイルの中に格納されているファイルを読み込むことが出来る (ファイルクローズは省略)。

import java.util.zip.*;


ZipFile file = new ZipFile("zipfile.zip");
Enumeration en = file.entries();
while(en.hasMoreElements()){
    ZipEntry entry = (ZipEntry)en.nextElement();
    String path = entry.getName();
    if(entry.isDirectory()){
        // ディレクトリの場合の処理
    } else {
        InputStream in = file.getInputStream(entry);
        // ファイルの場合の処理
    }
}

この標準機能にちょっとした問題がある。ほとんどの圧縮ツールがローカル環境のエンコーディング (Windows/Macintosh なら Shift_JIS、大抵のUnix は EUC-JP) でファイル名/ディレクトリ名を格納する一方で、Java 標準のこの機能は UTF-8 固定でしかファイル名を扱えないのだ。

例えば日本語ファイル名を含む ZIP ファイルに上記コードの entry.getName() は文字化けしたパスを取り出してしまう。さらに、この文字化けした ZipEntry から入力ストリームを取り出す file.getInputStream(entry) では null が返されるのである。

ZipFile を使わずに ZipInputStream から getNextEntry() を使った場合も、内部で同様のことが起きているのであろう、こちらは IllegalArgumentException が発生してしまうのだ。

java.lang.IllegalArgumentException
    at java.util.zip.ZipInputStream.getUTF8String(ZipInputStream.java:298)
    at java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:237)
    at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:73)
    …

例によって非 iso-8859-x 圏の人間を蹂躙した仕様というか何というか… とりあえずこれを回避してみよう。

続きを読む

PostgreSQL文字セット

PostgreSQL 8.0/8.1 の Windows 版をインストールする時、デフォルトの EUC_JP 以外の文字セット (UNICODE, UTF-8 など) を選択してはならない。

インストールで選択するのは initdb の際に用いられる文字セットなのだが、デフォルト以外を選択すると日本語で検索できなくなったりするのだ。ちなみに Linux 版だと initdb で UNICODE を選択しても問題はない。

なお CREATE DATABASE で指定する文字セットを EUC_JP 以外にして問題あるかは不明。

PreparedStatementのLIKE条件

JDBC の PreparedStatement LIKE 条件にワイルドカード付きでプレースホルダ (?) を設定する場合:

stmt = con.prepareStatement(
    "SELECT FOO FROM BAR WHERE NAME LIKE ?");
stmt.setString(1, "A%");

または SQL 内で % と連結させて:

stmt = con.prepareStatement(
    "SELECT FOO FROM BAR WHERE NAME LIKE ? || '%'");
stmt.setString(1, "A");

下の記述のほうがパラメータ設定時に LIKE を意識しなくても良さそうに見えるわけだが、後述するようにこれも結局は LIKE を意識しなければならない。どちらか良いかは単に好みの問題だろう。

シングルクォートで囲まれたプレースホルダは静的な文字列と見なされるため、以下のように記述するのは間違い。

stmt = con.prepareStatement(
    "SELECT FOO FROM BAR WHERE NAME LIKE '?%'");
stmt.setString(1, "A");

LIKE 条件に埋め込む値はワイルドカードがそのまま通ってしまうので、設定前にエスケープが必要。JDBC ではワイルドカードと見なしたくない % と _ の前に \ を置いてやれば良い。以下の例は 「100% Pure Java」で始まるレコードを検索する。

stmt = con.prepareStatement(
    "SELECT FOO FROM BAR WHERE NAME LIKE ? || '%'");
stmt.setString(1, "100\\% Pure Java");

値渡し/参照渡し

関数やメソッドに引数を渡す方法の呼び名。基本的には:

値渡し
呼び出し側の持ってる値がコピーされて渡される。呼び出し先でこの値を変更してもコピーなので呼び出し側には影響が無い。
参照渡し
呼び出し側の持っている値のメモリブロックそのものが渡される。呼び出し先での変更が呼び出し側にも反映される。

Java でのプリミティブ型は言うまでもなく値渡しだ。スタックに値がコピーされてから呼び出し先の処理が行われる。一方で、オブジェクトのインスタンスを渡した場合、呼び出し先で行ったインスタンスの変更が呼び出し元にも反映される。しかしこれを参照渡しと呼ぶとちょっといやらしいワナにはまる。

続きを読む

やってみせる

やってみせ 言って聞かせて させてみせ
ほめてやらねば 人は動かず

山本五十六

画像は拾い物。

地獄への道

地獄への道は善意で敷き詰められている

~ ウラジミール・レーニン

顧客が本当に必要だったもの

知り合いからの貰い物。立場による考え方の誤解や心理がうまく現れてる。ちょっと有名な図。

Management Lesson

Management Lesson

Management Lesson
    Never start a project unless all resources are available.

出展元失念。どこかで拾った画像。

迷走する船

船頭多くして船山に上る

設計するにしても管理するにしても、旗を振る人間が多いと返って統一がとれず目的とは違った方向に逸れ易くなる。

技術開発

アメリカの NASA は、宇宙飛行士を最初に宇宙に送り込んだとき、無重力状態ではボールペンが書けないことを発見した。

これではボールペンを持って行っても役に立たない。NASA の科学者たちはこの問題に立ち向かうべく、10 年の歳月と 120 億ドルの開発費をかけて研究を重ねた。

その結果ついに、無重力でも上下逆にしても水の中でも氷点下でも摂氏 300 度でも、どんな状況下でもどんな表面にでも書けるボールペンを開発した!!

 

一方ロシアは鉛筆を使った。

チャーチルのメモ

1940年、壊滅の危機に瀕した英国の宰相の座についたウィンストン・チャーチルは、政府各部局の長に次のようなメモを送った。

われわれの職務を遂行するには大量の書類を読まねばならぬ。その書類のほとんどすべてが長すぎる。時間が無駄だし、要点をみつけるのに手間がかかる。同僚諸兄とその部下の方々に、報告書をもっと短くするようにご配意ねがいたい。

  1. 報告書は、要点をそれぞれ短い、歯切れのいいパラグラフにまとめて書け。
  2. 複雑な要因の分析にもとづく報告や、統計にもとづく報告では、要因の分析や統計は付録とせよ。
  3. 正式の報告書でなく見出しだけを並べたメモを用意し、必要に応じて口頭でおぎなったほうがいい場合が多い。
  4. 次のような言い方はやめよう:「次の諸点を心に留めておくことも重要である」、「……を実行する可能性も考慮すべきである」。この種のもってまわった言い廻しは埋草にすぎない。省くか、一語で言い切れ。  思い切って、短い、パッと意味の通じる言い方を使え。くだけすぎた言い方でもかまわない。

私のいうように書いた報告書は、一見、官庁用語をならべ立てた文書とくらべて荒っぽいかもしれない。しかし、時間はうんと節約できるし、真の要点だけを簡潔に述べる訓練は考えを明確にするにも役立つ。

私の筆は "To do our work, we all have to read a mass of papers……" とはじまる簡にして要をえた文章の味を十分につたえていないが、大意はおわかり頂けると思う。<簡潔>はやがて第8章の主題の一つとなるはずである。

1) R.Barrass: Scientists Must Write - A guide to better writing for scientists, engineers and students, (Chapman & Hall, London, 1978).

ThinkPad: ナビゲーションキーの無効化

普段使っている ThinkPad X31 には [←] [→] キーの上にナビゲーションキーが付いている。これにはブラウザの 「進む」 「戻る」 に相当する機能が割り振られているのだが、場所が場所だけに間違って押して泣いたことも一度や二度ではない。ブラウザで長文を編集しなければならない人にはほとほと有難迷惑なキーなのだ。

そこでいろいろしらべてみたら、キーボードのスキャンコードと仮想キーのマッピングを Windows のレジストリで変更できるようだ。

WebDAV #3

WinXP + WebDAV の強みはインターネット上のファイルを共有ディレクトリとほぼ同じ感覚で扱えるところだ。つまり Word などのファイルをダブルクリックでシームレスに開けるということ。これを可能にしているのが WebDAV リダイレクター (WebClient) というサービスだ。

続きを読む

WebDAV #2

WebDAV を Basic 認証でアクセスさせようとしたのだがうまく行かない。どうも認証用のユーザ ID に Windows XP が勝手にサーバ名を付けて 「webdav-server\user-id」 という形式で認証させようとしているようだ。Apache の方はそれ全体をユーザ ID とみなすから、当然 「そんなユーザはいない」 ということになる。

いろいろ調べてみたらネットワークプレースの追加で末尾に ? を付ければ良いということらしい。まったく MS の独自挙動には泣かされる。

このほかに mod_encoding を使用しているなら NormalizeUsernameOn にすることで対処できるようだ。ただウチは初めから UTF-8 なので mod_encoding は入れていない。

ハードディスクを調べる

Linux の hdparm コマンドを使ってハードディスクを調べてみよう。

root@sapphire$ uname -a
Linux sapphire 2.6.12-1.1381_FC3 #1 Fri Oct 21 03:46:55 EDT 2005 i686 i686 i386 GNU/Linux
root@sapphire$ hdparm -V
hdparm v5.7

※このコマンドは ATA のパラメータを変更するためのものなので、扱いには十分注意してください。

続きを読む

WebDAV #1

自宅サーバに WebDAV をセットアップしてみた。HTTP を使って Windows ファイル共有のようなことが出来るシロモノだ。Windows 2000 から標準でサポートしており、特に XP からは普通の共有ディレクトリと同じく直接ファイルを開くような芸当もできるようになっているらしい。

ルーターが VPN に対応しているので個人で使う分には不要なんだが、リモートで共同作業する時のファイル受け渡し場所なんかに使えるかなぁと思っている。これからちょっと遊んでみて、使い物になりそうならここにまとめよう。

世界の標準日付フォーマット

Sun JDK 1.5 がサポートしている全てのロケールに対して標準の日付フォーマットを調べてみた。これは各ロケールに対する DateFormat.getDateTimeInstance()SHORT, MEDIUM, LONG, FULLSimpleDateFormat 形式で表したものである。

世界の標準日付フォーマット

ファイルアップローダー

昔作ったファイルアップローダーが全然知らないサイトで使われていた。懐かしさのあまりサイト管理者にメール入れようと思ったが、怪しげなアフェリエイトサイトのためかどこにもコンタクト情報が載ってなかった orz

こちらはというと引越しで Dynamic DNS の期限が切れてしまってそのまま放置状態。

XSL スタイルシート

XML 内で外部 XSL スタイルシートの指定の仕方をいつも忘れてしまうのでメモっておく。

<?xml version="1.0"?>
<?xml-stylesheet href="style.xsl" type="text/xsl"?>
<foo>
    <bar>hello, world</bar>
</foo>

<?xml-stylesheet?> の宣言と <xsl:stylesheet> の部分がどいつも頭の中で混乱する。

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="foo">
<html>
<body>
<xsl:value-of select="foo" />
</body>
</html>

</xsl:template>

</xsl:stylesheet>

Xvfb - 仮想フレームバッファ

Java 上で利用できるほとんどの画像操作用ライブラリは Java 標準の AWT をベースにしている。Unix 上で AWT を使用するためには X が起動されていなければならないが、サーバ用途の Unix ではそもそも GUI 環境がインストールされていないこともある。X が起動されていない状態で強引に AWT を利用しようとすれば以下のようなエラーが出るだろう。

torao@cobalt$ java Awt
Exception in thread "main" java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.
        at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
        at sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:63)
        at java.lang.Class.forName1(Native Method)
        at java.lang.Class.forName(Class.java:134)
        at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:64)
        at java.awt.Window.<init>(Window.java:191)
        at java.awt.Window.<init>(Window.java:233)
        at java.awt.Frame.<init>(Frame.java:318)
        at java.awt.Frame.<init>(Frame.java:297)
        at Awt.<init>(Awt.java:5)
        at Awt.main(Awt.java:9)
torao@cobalt$

もちろんこれは AWT から X にアクセスしようとして失敗しているのが原因だ。サーバ用途のマシンで常に X を立ち上げた状態にしておくというのは非常に無駄な話でもあるわけだが、AWT はサムネールやグラフなどの画像を作成するような場合に必要になってくる。

ここでは Xvfb (X Virtual Frame Buffer / 仮想フレームバッファ) と呼ばれているライブラリを導入してみよう。Xvfb は仮想的な X フレームバッファのみの環境を構築するため、X が起動していないマシンでも X のライブラリを使用するためのものだ。これさえ起動しておけばコンソールだけのサーバマシンでも AWT を使用した画像処理を行うことが出来るようになる。

続きを読む

ファイルのコピー

Java でのファイルのコピーは自前で実装するのが定石と言われていた。実際 BugParade でも File クラスにファイルコピーのメソッドは不要と言う形で close されている。

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4032604
It doesn't, and we have no plans to add such a method because (1) You can easily do this yourself, and (2) Its behavior would vary widely across platforms.

そんなのは簡単に作れるし、プラットフォームごとに挙動が異なるから、ということだ。しかし良く見るとこの回答がされたのは JDK 1.1 の頃であり、実は JDK 1.4 で追加された New I/O の?FileChannel#transferFrom()?/ FileChannel#transferTo() を使えば簡単かつ高速にファイルのコピーを行うことが出来る。

続きを読む
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フィード
リンク