CalendarとDate
今まで通っていた単体テストが、今日になって突然失敗するように。問題のコードは、古いファイルを消す処理で、今日から6か月前を求めるメソッドのテストだったんだけど、メソッド自体は、
calendar.add(Calendar.MONTH, -6);
で、単体テストの方は、今日現在の日付を元に、以下のコードと、テスト対象のメソッドとで結果が一致するかというテストが実装されていた。
date.setMonth(date.getMonth() - 6);Dateを無理矢理使ってテストという発想は面白いけど、現在の日付を使うのはだめだよね。テスト結果が環境に左右されてしまう。それにDate.setMonth()は引数の月には0以上しか許していないし。というかなんで今まで通っていたんだ、と思ったら、Dateクラスは負の月を設定すると、ちゃんと年を戻して対応するようだ。
となるとなんで今日になって失敗したんだろう。
Date date = DateFormat.getDateInstance().parse("2007/5/31");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
date.setMonth(date.getMonth() - 6);
calendar.add(Calendar.MONTH, -6);
System.out.println(date);
System.out.println(calendar.getTime());
Fri Dec 01 00:00:00 JST 2006 Thu Nov 30 00:00:00 JST 2006
ふ〜ん。6か月前は、11/31日になるけど、11月に31日は無いから、どちらかにずらすわけだ。Dateは12/1に、Calendarは11/30にずらすんだね。こんなのDateからCalendarを呼ぶようにしているのかと思ったら、別々にロジックが実装されてるんだ。
HTTP GETリクエストにおけるパラメータの文字コード
なんか面倒なことになっているな。とりあえず現段階での調査結果をメモ。
サーブレット仕様を厳密に解釈すれば、setCharacterEncoding()は、ボディ部しか規定しないので、GETリクエストにおけるパラメータは関知しない。
RFC2396では、URIでのキャラクタエンコーディングを規定していない。It is expected that a systematic treatment of character encoding within URI will be developed as a future modification of this specification.と言っている。
W3Cでのrecommendationによると、URIでの属性値は、UTF-8の使用が"recommend"されている。でも現実には、携帯端末のように資源が乏しい環境では、UTF-8は使用できないかもしれない。
サーブレットコンテナが、URIのキャラクタエンコーディングとして何を使うかは、サーブレット仕様には書かれていない(見つからなかった)。
Tomcatでは、server.xmlのConnector要素で、useBodyEncodingForURI="true"を指定することで、setCharacterEncoding()の設定をURIにも適用する(独自の対応)。
Jetty-6.1.3では、URIのキャラクタエンコーディングをJetty独自の方式で指定できる。
1) システムプロパティにキー名"org.mortbay.util.URI.charset"でエンコーディングを指定。 2) ServletRequestに"org.mortbay.jetty.Request.queryEncoding"というキー名でエンコーディングを指定。 3) 指定しないとデフォルトはUTF-8になる。
最初に考えたのは、サーブレットフィルタを使用して、ボディ部はsetCharacterEncoding()で変換、URIは自分で変換とする方法。しかしこれはサーブレットコンテナが、上記のサーブレット仕様を厳格に実装していることが前提になる。サーブレットコンテナによっては、setCharacterEncoding()の指定がURIのエンコーディングにも影響するものがあるようだし、それに上記のTomcat/Jetty独自設定が、配備先のサーバに対して行われているかもしれないし、いないかもしれない、よってこの方法をとったアプリケーションは、可搬性が大きく損われる。
さて、となると、現段階での結論は、インハウスアプリケーションなら、使用するサーブレットコンテナと相談。可搬性を重視するなら、昔のようにsetCharacterEncoding()を使用せずに、サーブレットフィルタで全て自分で変換する、かなぁ? でも、この時のエンコーディングに何を使うかが、問題だ。Jettyは何も指定しないとUTF-8になってしまうし。サーブレット仕様に規定が無いんじゃ、結局サーブレットコンテナに依存せざるを得ないんじゃないか?
JAXBContext
ピアノ発表会のページが、なんか重いなと思ったら、毎回JAXBContextを生成していた。そりゃ重いわけだ。測ってみたら普段のデスクトップマシンで300msくらいかかっていた。今のサーバ機だと倍以上かかっていたんじゃないだろうか。JAXBContextはスレッドセーフのようなので、シングルトンで共有するようにしてみたら、飛ぶように速くなった。
コジマを見てみたが、
少しくらい高くてもいいかと思ってSDカードを、近所のコジマで探してみたけど、秋葉の4倍以上の値段にめげて帰ってくる。こういうところで、ちゃんと利益を確保しているんだろうな。さすがだ。
SDカードが逝った。
なんか最近、やたらとザウルスがハングするなと思っていたら、とうとうアプリケーションのアイコンが?マークに。アプリケーションをSDにインストールしていたんで、みんな消えてしまった。データを入れていなかったのが幸い。この256MBのSDは、当時は35k円くらいしたんだよなぁ。それが今じゃ1k円切っているんだから、なんか虚しさを通り越して笑うしかない。
ブラームス
この曲は、技巧的には特に難しいところは無いのだけど、とにかく緻密で計算し尽くされた音楽なので(まぁブラームスの曲は、みんなそういう傾向があるけど)、ちょっと和音が崩れたり、音量やテンポを間違えると、すぐに破綻してしまう。なので実際に弾くのは、すごく難しい。
コンピュータで演奏させる場合は、いくらでもやり直しができるので、その点はいいんだけど、やはり感情を入れるのが、なかなか難しい。結局、どっちにせよやっかいな曲だ。
やたらとタイが多いので、タイ入力を簡単に行える機能も追加してみた。
Vista DSP版
PCからPCへの移動は制限が無くなったかと思っていたんだけど「セットで購入したハードウェアを使い続ける限りは」と書いてあるね。ということは、そのハードウェアが壊れたら事実上、ライセンス消失なの? USBとかeSATAの外付けDVDドライブと買うのは無しなんだろうか。外さなければOK?
おうちで核融合
きしださんとこで知った。これって三重水素の核融合だから、できたんだろうね。重水は、それ自体には強い毒性とか放射能とか無いから危険性少ないし。これがウランとかプルトニウムで核分裂っていうんじゃ、ちゃんとした設備が無いと実験者は、実験成功前に体を壊すと思われ。
WoW休眠
とりあえず最近、全然やらないんでWorld of Warcraftのクレジットカード登録を削除した。そしたら「キャラは今のところ抹消する予定は無いので、気が向いたら戻ってきてね」って。なんだ、それならもっと早くやめればよかった。てっきりキャラクターデータが消えちゃうんだと思って、悩んでたんだよね。
commons-logging
ここ数日、このあたりを追試していたりしてたのだけど、commons-loggingも1.04だとやばいけど、1.1なら、よほど変なデプロイしない限りは、問題になることは無さそうだ。SLF4Jもちょっと微妙になってきたかな。でもJettyはSLF4Jに乗り換えたらしい。まぁ、スタティックリンクの方が圧倒的に分かり易いというメリットは、あるわけだけど。
Tomcat6のクラスローダ。
へ〜、ちゃんと親のクラスローダが分かるようになっているんだ。これは分かり易いね。
WebappClassLoader delegate: false repositories: /WEB-INF/classes/ ----------> Parent Classloader: org.apache.catalina.loader.StandardClassLoader@c53dce
Tomcat6.0 マネージャからのdeployでNullPointerException
時折deployがNullPointerExceptionで失敗する。以下の場所で落ちているようだ。
--- HTMLManagerServlet.java (Line 434) --- args[11] = new Integer(context.getManager().getMaxInactiveInterval()/60);
上の方のコードを見てみると、
if (context.getManager() != null) {
args[4] = new Integer
(context.getManager().getActiveSessions());
} else {
args[4] = new Integer(0);
}
どうもcontext.getManager()はnullのケースがあるようだ。とりあえず、以下のようにして逃げる。
if (context.getManager() == null) {
args[11] = new Integer(0);
}
else {
args[11] = new Integer(context.getManager().getMaxInactiveInterval()/60);
}
P.S. あ〜、Tomcat6.0はJDK5が前提だからInteger.valueOf(int)を使った方が望ましいね。
Tomcat6.0 Deployer
Managerアプリ的にはデプロイの時に、warファイルだけではなくてディレクトリも指定できるんだけど(実際manager/htmlでは受け付けてくれる)、ant taskの場合には、どうもwarしか受け付けないようだ。
/home/shanai/docs/sample/logging01/build.xml:40: java.io.FileNotFoundException: /home/shanai/docs/sample/logging01/deploy (Is a directory)
面倒だけどwar作るしかないかな。
にゃんこ生活が403になる件。
Ubuntu+Firefoxからだと、にゃんこ生活が403になってしまう。Operaだと大丈夫なんで、UAを見ているっぽい。試しにUser Agent Switcherを入れて調べてみたら、IEでもNetscapeでもOperaでもok。ロリポップってFirefoxに恨みでもあるんだろうか。
カシオトーン見てきた。
近所のコジマで見てみたけど、やっぱり30k円以下のやつだと、かわいそうだね。単にバネで鍵盤を固定してあるだけって感じなんで。でも4万台のやつだと、タッチもそこそこで、音も昔に比べるとちゃんとピアノの音がするし、とりあえず「いつ、やめちゃうか分からないし」って向きには、いいんじゃないだろうか。ちゃんと88鍵あったんだけど、音やタッチをあのクオリティのまま、もっと鍵数少なくして安くしたのがあるといいんだけどね。88鍵なんて、よほど上達しない限り不要だし。
Tomcatその後。
6.0だと何の問題も無く、動いた。5.5も、何度か試すと、動いたり動かなかったり。Windwsだと問題ない(exeの方じゃなくて、普通にzip展開で、bin/startup.bat起動)。どうもタイミングに依存する問題があるような感じだ。
Tomcat 5.5 on Ubuntu
なんかManagerアプリが動かない。BASIC認証のダイヤログが表示されずに、いきなり403になる。試しにweb.xmlの中のsecurity-constraintから/html/*を外してみたら、今度はなぜかClassNotFoundになるし。
java.lang.ClassNotFoundException: org.apache.catalina.manager.HTMLManagerServlet at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) ...
ちゃんとserver/webapps/manager/WEB-INF/libにcatalina-manager.jarはいるんだけどな。なんかクラスローダまわりが変になっている感じだな。しかしサンプルとかは、ちゃんと動くんだよなぁ。ちょっと古いJDKにして試してみるか。
BigDecimal
やっぱり面倒だなBigDecimal。大量の10進演算が必要なバッチなんかは、Javaで書くよりCOBOLとかの方が生産性、保守性が高いんじゃなかろうか。Stringが+で連結できるように、BigDecimal/BigIntegerの四則演算くらいは、言語側で+-*/をサポートしてくれても良さそうなもんだが。
電子ピアノ
相談されたものの、予算が30k円だとカシオトーンで決まりだろうか。しかしまぁ、安くなったもんだ。でもなんか普及価格帯のものばかりで、それ以上お金出しても、デザインが凝ってるとか、音色が256色ありますとか、どーでもいい方向に行ってしまう。純粋にピアノの音色とか、タッチを向上させるという方向性のものが皆無に等しいのは、どういうわけだろう。本物のピアノが売れなくなるから作らないんかな。
無線アクセスポイント故障
なんか最近遅いなとは思っていたんだけど、夜だからプロバイダが混んでいるんだろうと思っていた。ふとローカルサーバにftpしてみると、2-30kb/sしか出ていない。音楽サーバの音が途切れたりしていたのは、このためだったのか。もう3-4か月、気付かなかったことになるな。結構2-30kb/sあると、巨大なファイルとか落とさなければ分からないもんだ。仮に落とそうとして遅かったとしても「たまたま相手のサーバが遅いんだろう」とか「隣の家で電子レンジ使ってるんだろうか」くらいに思ってしまうし。
で、秋葉原に行って「最近は安くなったねぇ」なんて呑気に構えて有線のルータ買ってくるし。つくづく自分の、おっちょこちょい加減にあきれるばかり。まぁ4k円切っていたのが幸いだ。仕方無いので近所のコジマに行ってNETGEARのWGR614Cというのを買ってきた。
最近は、もうアクセスポイントというのは無くて、みんなルータなのだ。試しに、これをルータにしてポート80をサーバー機にフォワードする設定にしてみたが、全然つながらず。というか固定IPアドレス契約なのに、つなぐたびにIPアドレスが変わるし。わけわからん。単なるアクセスポイントとして使用するのに設定ではまる。ルータのDHCPをonにしないとルータが設定できない。で、DHCPが提供するデフォルトゲートウェイのIPアドレスをサーバー機にしたいのだけど、ルータのIPアドレス固定になってしまう。あれこれいじって、なんとか設定できた。初心者向けに簡単なウイザードがあるのはいいんだけど、そのせいでちょっと凝った設定をしようとすると、えらく面倒なことになる。
昔、買ったNECのISDNルータRT52iには、ちゃんとコマンドリファレンスがついてきたけど、今回買ったやつには、2つとも、そんなものはついてこなかった。そういえば昔は、プリンタ買うと、ちゃんとESC/Pのコマンドリファレンスがついてきたよな。良くも悪くもコモディティ化したということか。
ピアノ発表会のページをi18n化
といっても英語だけだけど。internationalizationに国際化という意味があるから「i18n化」って言い方は変か...
AmazonのリンクってIFRAME使うから、XHTMLのバリデータに通らなくなってしまう...
NetBeans 5.5に戻る。
6.0は何かの拍子にキー入力を受け付けなくなって、そのまま立ち上がらなくなってしまった。で、5.5に戻る。JSPで軽いアプリケーションを書くには極楽(欲を言えば、importを自動で挿入して欲しい)なのだけど、うっかり出力ペインの中にあるTomcatログのxをクリックして消しちゃった時って、どうやって復活させるんだろう。ウィンドウメニューの中を散々探し回ってみたけど、見つからない。立ち上げ直したら戻ったから、大した問題じゃないんだけど、
NetBeans6.0m9
Consoleの部分のフォントって変更できないんだろうか。日本語が豆腐になってしまって読めないよ。
あ、そうかLinux用JDK6.0自体がデフォルトではSwing上の日本語が表示できないんだった。
fallbackを作ってやって解決。しかしなんでこんなにフォントが汚いんだろう。
endorsed
昔作ったxhtmlライブラリを最新のjaxbで書き直してみた。com.sun.xml.bind.xmlDeclarationが無くなったようだ。
// m.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE);
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
で、デプロイしてみたらjaxb-2.1のAPIが必要だけど、jaxb-2.0のAPIがブートストラップクラスローダから読まれているから、endorsedで解決してねというエラーになる。
2007-05-05 02:09:51 StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI (from jar:file:/data/www/WEB-INF/lib/jaxb-impl.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.1 API. Use the endorsed directory mechanism to place jaxb-api.jar in the bootstrap classloader. (See http://java.sun.com/j2se/1.5.0/docs/guide/standards/)
で、指示通りにendorsed作って、jaxb-api.jarを放りこんでみたんだけど、全然置きかわらないんですけど。う〜む、なんでなんだろう。仕方無いんで、rt.jarからjavax/xml/bindの下を削除してしまった(<おい)。
jaxbのインストーラでぬるぽ
久しぶりにjaxbでも使ってみようかと思い、2.1.3を落としてきてjava -jarしてみたら、Ubuntuだと、NullPointerExceptionで落ちる。
shanai@shanai-laptop:~/Desktop$ java -jar JAXB2_20070413.jar
Exception in thread "main" java.lang.NullPointerException
at javax.swing.plaf.synth.SynthLookAndFeel$AATextListener.propertyChange(SynthLookAndFeel.java:789)
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:339)
...
で、調べてみると、これのようだ。でも、この記述ならば最新の6.0なら直っていそうだよね。このへんでも「なんで直ってないんだろうね?」って書いてある。回避策はUIManager.getInstalledLookAndFeels()を呼ぶということらしいけど、面倒なんでexport LANG=enで起動してみたら、動いた。
Ivory、だんだん遅くなる。
使い続けていると、だんだん反応が遅くなってくる。アプリケーションを立ち上げ直すと直る。何が悪いんだろうか。今まではVsthostを使っていたのだけど、そういえばE-MU 0202に色々付いてきていたなぁと思い、片っぱしから入れてみる。Cakewalk SONARを使ってみたら、だめだこりゃ、しょっぱなから話にならないくらいヨレヨレ。しかしなぁ、Ivoryの最低スペックってPen4 2.4GHzだったと思うんだけど、3.2GHzで満足に動かないってどういうことよ。Core 2値下げになったしE6420あたり買ってみるかな。
StringTokenizer
API仕様書を見ると、もう時代遅れだから使わないでねと書いてある。でも一番速いと思うんだよな。ちょっと試してみた。約65MBのCSVをディスクから読み込む処理。
StringTokenizer: 4.0s String.split(): 7.4s Pattern.split(): 7.3s
意外とString.split()が速い。正規表現のコンパイルが入るから、もっと重いかと思っていた。もっとも","だからか。メモリから読むならもっと差は開きそうだけど、2倍までは開かない感じか。これなら手軽さでString.split()、パターンが複雑ならPattern.split()を使うという選択もありかな。








