Commons-collections
TreeListが気に入った。削除、挿入、get(n)、いずれもそこそこ速い。Collections.binarySearch()と組み合わせれば、順序付けも簡単。しかしGenerics対応はいつなんだろうか。
成分解析
デスマーチの成分解析結果 : デスマーチの67%は食塩で出来ています。 デスマーチの18%は大人の都合で出来ています。 デスマーチの13%は鍛錬で出来ています。 デスマーチの1%は覚悟で出来ています。 デスマーチの1%は陰謀で出来ています。
絶妙だな。食塩は汗ということか。
ポンドは、なんで"lb"って書くの?
Wikipediaから。
「歴史的には、メソポタミア地方で大麦1粒の重さを元にグレーンが定められ、その倍量単位としてポンドが定められた。古代ローマではこの単位を「リブラ(libra)」(天秤の意味)と呼んでおり、これがポンドを表す記号"lb"の由来である。また、通貨の単位のポンドの略号"£"もlibraに由来する。「○リブラの重さ」を"○ libra pondo"と言い、この"pondo"が質量の単位となった。」
ふ〜ん。なんだかわかったようなわかんないような。ポンドもリブラも単位の呼び名のようだけど、なんでそれをつなげちゃったんだろう。
回避方法
とりあえず、windowClosed()の方にSystem.exit()を移動すると大丈夫のようだ。この方がなんかしっくりくるね。でも多分バグだろうからBug Paradeには入れておいた。
@Override public void windowClosing(java.awt.event.WindowEvent evt) {
dispose();
}
@Override public void windowClosed(java.awt.event.WindowEvent evt) {
System.exit(0);
}
windowClosingでSystem.exit()するとハング
public class Test extends javax.swing.JFrame {
public Test() {
setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(new java.awt.event.WindowAdapter() {
@Override public void windowClosing(java.awt.event.WindowEvent evt) {
System.exit(0);
}
});
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Test().setVisible(true);
}
});
}
}
WindowsXP + jdk5.0_06だとxボタンを押したところで固まる。でも別のWindows2000 + jdk5.0_06環境だと大丈夫だった。何なんだろう、うちの環境だけの問題なのかな。
今日みつけたバグ
int num;
void foo() {
synchronized (new Integer(num)) {
...
}
}
プリミティブ型は、synchornizedステートメントに指定できないから、苦しまぎれにIntegerにラップしてみたんだろうな。もちろん、これは全く同期されない。privateなロック用オブジェクトを用意しないといけない。
int num;
private final Object lock = new Object;
void foo() {
synchronized (lock) {
...
}
}
JAXBでDTDのDOCTYPE宣言を出力
前にちらっと書いたJAXBでXHTMLを生成する方法でリンク集のページを書いてみた。結構いい感じだ。やっぱりプログラミング言語は強力。
ひとつ困ったのは、XHTML 1.0のStrictを使う場合、頭にDTDのDOCTYPE宣言を入れないと、w3cのバリデータ様がお怒りになってcomplienceテストに通らない事。で、JAXBでこれをやるには、どうすればいいのか良く分からなかった。結局宣言部をJAXBに出力させないようにして回避。
PrintWriter pw = new PrintWriter(out);
pw.println("<?xml version=\"1.0\" encoding=\"Shift_JIS\"?>");
pw.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"");
pw.println("\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
pw.flush();
renderMyPage();
Marshaller m = jaxbContext.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_ENCODING, "Shift_JIS");
m.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE);
m.marshal(HTML, out);
out.flush();
なんだかなぁという感じだけど、
あとはJSPにするかどうか。この仕組みならJSPにする必要なんて無いのだけど、JSPはホットデプロイが出来るから、楽なんだよね。ほんとにそれだけのため。本体が全て<% %>で囲まれているJSPなんて初めて書いた。とはいえやっぱりエラーが起きた時とか面倒だしエディタも使いにくい。JSPは継承が使えないのも痛い。extendsディレクティブで既存クラスからの継承はできるけど、JSP同士での継承が出来ないんじゃ、結局親クラスはwarに入れなきゃならないわけで。やっぱりJSPは使わない方がいいかもしれない。
[備忘録] Pebbleをjdk5.0で動かすとTransformerFactoryImplが無いと言われる。
javax.xml.transform.TransformerFactoryConfigurationError: Provider org.apache.xalan.processor.TransformerFactoryImpl not found
直接実装クラスをアプリケーションから指定しているの原因。1.4までは標準ライブラリに入っていたのが、5.0では無くなったのが原因のようだ。xalan-jを入手してxalan.jarとserializer.jarを、WEB-INF/libにコピーしてやると直った。
バッテリー交換
といってもPCではなくて、車のバッテリー。2年以上たって最近エンジンが1回でかからないこともあるので、交換することにした。いつも正極と負極のどちらを先にはずすのか迷ってしまう。なんとなくプラス側を先に外したくなるけど、車体は負極とつながっているので、プラスを先に外そうとすると、作業中にレンチが車体と触れた途端ショートしてえらいことになる。
古いバッテリーを引き取りに出そうかと思ったら、レシートが見つからない。昨日出しておいたはずなんだけど、しまっちゃったのかな?
屋外でEF135mm f2
屋外でも使ってみた。いずれも開放。

コントラストの高いところは、若干にじんでソフトフォーカスがかかったような感じになる。使いこなしが難しい感じ。

開放でも解像度は良好。

チューブをつけて、マクロがわりに。
Tinnyさんちに遊びに行ってきました。
さび猫は、デフォルトで撮っても、いまひとつきれいに撮れない。これはカメラのデフォルト設定。白っぽく色が抜けた感じになってしまう。
RAWで撮ってWBを調整。コントラスト中心を思いっきり下げた上でコントラストを上げ、ガンマもやや下げると柄が鮮明になってくる。更に若干彩度を稼ぐことで、大体目で見た印象と同じ感じになった。撮る時は、+1/3から2/3くらいの露出補正をしておくと良いようだ。
ラップされているか教えて欲しい。
「念のためBufferedOutputStreamでバッファリングしておこう」とか「Collections.unomidifiableListで変更不可にしておこう」とか。気づくと何重にもラップされていたり。
前者は、自分でも回避できる。受けとったストリームがinstanceof BufferedOutputStreamだったら、やらなければいいわけだ。でもバッファサイズが違ったりするかもしれないし。バッファサイズが自分の想定より大きければバッファリングしないとかできればいいんだけど。サイズが外から分かればね。
後者は、ちょっと無理だ(型名を見れば分からないでもないけど、そこまでやる気にはならない)。UnmodifiableCollectionはパッケージプライベートだから手が出せない。Collections.unmodifiableXXX()の中で同様の処理をしてくれればいいんだけど。
ジェネリクス
これって何でエラーになるんだろ。
static List<Comparable<Integer>> getList() {
return new ArrayList<Integer>();
}
D:\tmp\test\src\test\Main.java:29: 互換性のない型
検出値 : java.util.ArrayList<java.lang.Integer>
期待値 : java.util.List<java.lang.Comparable<java.lang.Integer>>
return new ArrayList<Integer>();
と思ったら、そうか、これがエラーになるのと同じ原因か。
List<String> list = new ArrayList<String>();
List<Object> list2 = list;
ワイルドカードならok。もっとも戻り値に要素の追加はできなくなるけど。
static List<? extends Comparable<Integer>> getList() {
ファイル共有
どうも最近は、単純なファイル共有はうまく行かないようだ。今はみんなエクスプローラを使うもんだから、ちょっとした操作ミスで甚大な被害が起きる。良くあるのがディレクトリごとどっかに移動されてしまうミス。
やっぱりちょっと面倒でもTortoiseSVNとか覚えてもらうしか無いんだろうな。
Google Desktop
これって自分が見た記事に関連しているページを芋づる式にひっぱってくるの? それともたまたまなのかなぁ。右クリックすると「このタイプのアイテムを表示しない」ってのがあるけど、どのくらい賢いんだろうか。記事があふれてしまって結局見きれないよ。
RandomAccessFile
書き込んだ内容をファイルに反映させるのはclose()するしか無いんだろうか。なぜかflush()が無い。1.4からは"rwd"というモードにすると、反映するようだが書き込みリクエストで毎回じゃ遅くなって困る。getFD().sync()したら、書き込んでくれるのかなぁ。下位層のファイルシステムにフラッシュを要求するようだけど、RandomAccessFile自身がキャッシュしていることは無いと考えていいのだろうか… みんなnative methodだから調べる気にならない…
主電源OFFで消費電力ゼロワット
ここを見ると主電源offだとリモコンきかないようだけど、単に物理的に回路をoff/onするメインスイッチが付いているだけってことじゃないの? 結局リコモンがきかないと面倒でスイッチ切らない悪寒。
too, also, as well
ロングマンから。
alsoが最もフォーマルで、as wellが最もくだけている。
節の先頭にtooを使用してはいけない。
一般にはalsoは節の最後には置かない。
否定文ではeitherを使用する。
赤外線通信できなくなった。
PCからケータイに送ろうとすると「ファイルは次の操作中にエラーが発生したため送信されませんでした。操作: ワイヤレスリンクがほかのコンピュータにファイルデータを送信しているときデータが無効です。」と表示されるようになった。どうやらXP SP2のバグのようだ。なんか書いてある回避策も効かないし、困った。しかたないのでザウルス経由で転送。
なんか登載メモリーが多い時にハイバーネーションに失敗するバグもずっと直らないし、XPっていまいち。
ロギング難しい
アプリケーションサーバに配備された複数のアプリケーションで、それぞれ別の設定でロギングしたいとする。これはロギングライブラリを共通のクラスパスに入れないで、アプリケーションそれぞれのwarファイルに入れれば良さそうだ。
でも、特にオープンソース系のアプリケーションサーバでは、アプリケーションサーバ自体も同じロギングライブラリを使っていたりする。
SRV.9.7.2によると"It is recommended also that the application class loader be implemented so that classes and resources packaged within the WAR are loaded in preference to classes and resources residing in container-wide library JARs."なので、共通クラスパスと、WARだったらWAR内を優先すべきということになるのかな。サーバが立ち上がってすぐの状態で、まだアプリを読み込んでいない状態なら、当然共通クラスパスから読むだろうし、アプリケーションが上がって来たら、今度はWARから読むだろう。別々のクラスローダから読まれたクラス間には互換性が無いので(Java言語仕様書4.3.4)、これは例外の発生を招くと。
結局アプリケーションごとにロギングの設定を変えたいというのは無理という感じになる。でもまぁパッケージ名で設定変えられるんだし、いいじゃんという気もするけど。その場合はWARにはロギングライブラリを入れないで、共通側のみを使えばいいのかな。でもそうするとそのWARは、特定のロギングライブラリが使われているサーバ限定ってことになっちゃうなぁ。
あるいは、全く発想を変えて各ログメソッド呼び出しごとに、コンテキストを判断して設定を切り替えるようにする。でも遅くなりそう。
諸刃のつるぎ
「諸刃のつるぎ」って英語では何ていうのかな、と辞書をひく。
two-edged, double-edged
あれれ?
どうやら、自分はずっと勘違いをしていたようだ。諸刃って束の部分が無くて、モロに刃が出ているつるぎだと思っていたよ。
ここに例があった。まさにdouble-edgedだね。あれかな、相手が切りかかってきたのを刀で受けた時に、諸刃だと、自分のおでこが切れちゃうってことなのかな。
jaxbでちょっと遊び。
servletでprintln(HTML)もイヤだけど、JSPの「"」と「'」のネスト合戦や、EL式やJSTLをこねくりまわすのもイヤ。
んで、ここにxhtml 1.0のdtdが落ちているので、こいつをjaxbに喰わせてやったら全部オブジェクトモデルでxhtmlを表現できるなぁと。
jaxbのxjcに-dtdオプション付けて読ませようとしたら、xhtmlの属性名にclassがあって、これがJavaのclassとぶつかるので、エラー出て変換できない。xsdならbindingルールを指定できるのだけど、dtdではどうもできないっぽい。サクっとあきらめて、trangでdtdからxsdに変換。これに以下のbindingルールを付けてxjcでクラス群に変換。
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="DTD/xhtml1-strict.xsd" node="/xs:schema">
<jxb:bindings node="//xs:element[@name='block']">
<jxb:class name="SmallBlock"/>
<jxb:property name="SmallBlock"/>
</jxb:bindings>
<jxb:bindings node="//xs:element[@name='inline']">
<jxb:class name="SmallInline"/>
<jxb:property name="SmallInline"/>
</jxb:bindings>
<jxb:bindings node="//xs:element[@name='map']//xs:attribute[@name='class']">
<jxb:property name="class1"/>
</jxb:bindings>
<jxb:bindings node="//xs:attributeGroup[@name='coreattrs']//xs:attribute[@name='class']">
<jxb:property name="class2"/>
</jxb:bindings>
<jxb:bindings node="//xs:attributeGroup[@name='i18n']/xs:attribute[@name='lang']">
<jxb:property name="langCode"/>
</jxb:bindings>
<jxb:bindings node="//xs:element[@name='bdo']//xs:attribute[@name='lang']">
<jxb:property name="langCode"/>
</jxb:bindings>
<jxb:bindings node="//xs:group[@name='head.misc']//xs:choice">
<jxb:class name="HeadMisc"/>
<jxb:property name="HeadMisc"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
JavaDoc出してみたら、10分もかかったよ。ドキドキしながらオブジェクトモデルでxhtmlを書いてみる。こんな感じになる。
Html html = objFactory.createHtml();
Head head = objFactory.createHead();
html.setHead(head);
Title title = objFactory.createTitle();
head.getContent().add(title);
title.getContent().add("Hello!");
Body body = objFactory.createBody();
html.setBody(body);
final Br BR = objFactory.createBr();
P p = objFactory.createP();
body.getBlockOrFormOrMisc().add(p);
p.getContent().add("Hello");
p.getContent().add(BR);
p.getContent().add("World");
これをjaxbのマーシャラに喰わせれば、xhtmlが出力される。
<?xml version="1.0" encoding="Shift_JIS" standalone="yes"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello!</title>
</head>
<body>
<p>Hello
<br/>World</p>
</body>
</html>
傍から見たら、やっぱり狂気だろうか。でも個人的には気に入ってしまった。だってコンパイル段階でかなり静的なチェックできるしマーシャラがある程度の構造のバリデーションしてくれるし、不等号とか&とかエスケープしなくていいし、タグの閉じ忘れとか起こり得ないし、ループとか条件分岐は楽勝だし、テストはオブジェクトモデル段階でassertすればokだし。OOがフル活用できるからデザイン統一とかも楽勝な気がするし、自分のページ全部書き直してみようかな。
SLF4JとNLF4J
久しぶりに、Commons-Loggingを見に行ったら、1.1が出たように見えるんだけど、downloadsに行くと1.0.4しかない。1.0.5はcancelされてるし。
と思ったら、log4jの作者はSLF4JとNLF4Jに移行しているようだ。そういえば、これってこの辺で見た記憶があるんだけど、この解説記事だと単に新しい選択肢が出来ただけ? としか見えなくて、そのまま通り過ぎていた。
でも、これらは遥かに重要な意味を持っていることが分かった。基本的にはCommons-Loggingとlog4jは近い将来、obsoleteになりそうだ。新しいロギングAPIが必要になった理由は、Ceki自身がここで解説していて、クラスローダまわりのややこしい仕様のために、Commons-Loggingがいろいろといやらしい問題を引き起こす例が、詳細に述べられている。
自分でこれから作るクラスは、SLF4Jを使うとしても、色々なオープンソースを組み合わせて使うケースでは、Commons-Loggingを使っているコンポーネントだって使わなきゃならない。その場合は、jcl104-over-slf4j.jarを使って段階的に乗り換える方法があるようだ。
[備忘録] NetBeans 5.5でカスタムビルド(javac)
例えばJAXB使って、XSDからjavaのソースを生成、コンパイルしたいとかいう場合。もちろんbuild.xmlの中に-pre-compileターゲットを作って、そこでxjc呼んでからjavacなり好きにやれば良いのだけど、この時に呼び出すjavacのバージョンとかCLASSPATHとかをNetBeans側のプロジェクトの設定に合わせたい。そういう時はjavacマクロが定義されているので、それを使うと良い。build.xmlのprojectエレメントに名前空間を追加して、
<project name="profilerUI" default="default" basedir="." xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:j2seproject2="http://www.netbeans.org/ns/j2se-project/2" xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1">
あとは、javacのかわりにj2seproject3:javacを使う。
<j2seproject3:javac srcdir="generated/src" destdir="generated/build"
classpath="${libs.jaxb-1.0.6.classpath}"/>
equals()/hashCode()はミュータブルクラスではオーバーライドすべきでない。
artonさんがFindBugs本で書いている通り、ミュータブルなクラスでは、equals()/hashCode()をオーバーライドすべきではない。java.awt.Pointなんかは、ミュータブルでありながら、equals()が実装されているが、これはそもそもフィールドをpublicにさらした事が間違いだし、しかもhashCode()が実装されていないので、Objectの契約にも違反している(原文だと"generally necessary"だから、違反までは行かないかな)。もっとも値が変わるオブジェクトをHashMapやHashSetに入れたら、何が起こるか分からないので、これらのコンテナにPointを放り込むことを想定していないのだと思われる(API仕様書に一言あってもいいと思うのだが)。StringBufferがequals()を実装していないのも、StringBufferがミュータブルだからだろう。
しかしObject.equals()/hashCode()の説明に一言「一般にはミュータブルクラスでは実装すべきではない」と書いてあっても良さそうなものだ。
今度はSuicaが増殖?
みんな挙って、この手のローカルSuicaカードを出しまくるんだろうか。で財布の中は、ポイントカードのかわりに大量のSuicaカードが。複数のSuicaを同時に改札に提示すると、どれが使われるんだろう。というか、そろそろどっかでポイントのアグリゲーションやってくんないかなぁ。そちらの方が、電子マネーよりもよっぽど需要があったりしない?












