2010年01月27日

Java の for の書き方

List list;

があるときに、次のようなコードを書くのは普通のことだが、

for (Item item: list) {
    foo(list, item);
}

ここでちょっとした罠があって、エラーになってしまうことがある。

Caused by: java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
	at java.util.AbstractList$Itr.next(AbstractList.java:343)
	at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:555)

何が起こったのか。ループの中で list の要素を入れ替えたのだが、それが気に入らないらしい。これは、次のように old style で書いておけば問題ない。

for (int i = 0; i < list.size(); i++) {
    Item item = list.get(i);
    foo(list, item);
}

これだとその都度 index を使って list から要素を取り出すのだろう。じゃあ先程のは一体何をやっているのか、というのはちょっと気になる。

2009年11月06日

Subversion を使っています

毎週金曜に、開発チームの定例ミーティングをやっていて、今日のテーマは subversion。開発のバージョン管理は subversion を使っている。定番ツールなので説明するまでもないと思うが、こちらで使っているのは、Windows 上での TortoiseSVN、Eclipse 上で subclispce 等だ。

TortoiceSVN は、http://tortoisesvn.tigris.org/ が公式サイト。最新版は 1.6.6. 最近 1.6.5 から update されたような気がする。

Subclipse はこのあたりにある。http://subclipse.tigris.org/ Eclipse の help - Install new software のところで、http://subclipse.tigris.org/update_1.6.x を指定して、後は適当に。こちらは 1.6.5 というバージョンになっていた。

どんな使い方をしているのか、後日紹介したいと思う。

2009年07月20日

Eclipse の Reference - Project で internal error

これは何だろう? Reference - Project で結果が表示できない。

An internal error occurred during: "Java Search".

java.lang.IllegalArgumentException: Class file name must end with .class
at org.eclipse.jdt.internal.core.PackageFragment.getClassFile(PackageFragment.java:182)
at org.eclipse.jdt.internal.core.util.HandleFactory.createOpenable(HandleFactory.java:109)
at org.eclipse.jdt.internal.core.search.matching.MatchLocator.locateMatches(MatchLocator.java:1174)
at org.eclipse.jdt.internal.core.search.JavaSearchParticipant.locateMatches(JavaSearchParticipant.java:94)
at org.eclipse.jdt.internal.core.search.BasicSearchEngine.findMatches(BasicSearchEngine.java:223)
at org.eclipse.jdt.internal.core.search.BasicSearchEngine.search(BasicSearchEngine.java:507)
at org.eclipse.jdt.core.search.SearchEngine.search(SearchEngine.java:551)
at org.eclipse.jdt.internal.ui.search.JavaSearchQuery.run(JavaSearchQuery.java:144)
at org.eclipse.search2.internal.ui.InternalSearchUI$InternalSearchJob.run(InternalSearchUI.java:91)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

eclipse.buildId=I20090611-1540
java.version=1.6.0_14
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=ja_JP
Framework arguments:  -product org.eclipse.epp.package.reporting.product
Command-line arguments:  -os win32 -ws win32 -arch x86 -product org.eclipse.epp.package.reporting.product -clean

2009年07月04日

pcがフリーズしたのでメモリを抜いてみた

subversion サーバーにしていた pc が動かなくなった。DELL の PowerEdge SC430 である。完全に操作不能なので電源を強制的に切って、再起動すると、Uncorrectable memory error と表示されている。

よく分からないのだが、F1 を押して起動させてみると、とりあえず動作した。subversion のレポジトリを全部コピーして、gzip で圧縮しようとしたら、ここで応答がなくなった。何も対策していないのだから当たり前なのだが、どうも本当にメモリーが壊れたような感触だ。

本体内に掃除機をかけてみたり、メモリを抜き差ししてみたが改善されない。

このpcは、256MBのメモリが4枚の構成になっている。ならば、2枚抜いてみて、それがエラーの原因になっているメモリだったら解決するのではないだろうか? もしエラーが再現するのなら、抜いたものと入っているものを入れ替えてみればよい。

ということで、半分の512MBのメモリ構成にしてみたら、その後はフリーズしないので、ビンゴだったようである。subversion のサーバーという用途であれば、このメモリ量でも十分だ。

2009年05月30日

JIRO に Excel で作った CSV のデータを取り込むときのコツ

JIRO にデータをインポートする方法はいくつかあるが、CSV のデータを作っておいて取り込むのが一番標準的である。この場合、XML で取り込む時とは違って、データ型が曖昧なので、いろいろなことが起こる。例えば日付を想定したフィールドに「未」という文字が入っていたら、そこだけ Date ではなく String のオブジェクトとして取り込む。

今回ハマったのは番号の取り込みなのだが、12桁の番号が、CSV に書き出した時点で、2.3456E+11 のような文字列になってしまっている。数値のように見えるのだが、0で始まるときに困るので、このカラムの書式は「文字列」に指定してあるのだが、なぜこういう表現になるのか分からない。とりあえず、このセルをダブルクリックすると12桁の数字に戻る。全部そういうことをすればよさそうだが、面倒すぎる。

そこで、何気なく、Excel でこのカラムの書式指定を「文字列」ではなく「数値」にしてみたら、一瞬で12桁の数字になった!
 つまり、Excel 的には、

書式が文字列 → 2.3456+11
書式が数値 → 234567890123

ということらしいのだが、若干釈然としない。しかしとりあえず問題は解決した。いやまて、先頭が0の場合はどうなるのだ?

2009年05月05日

Java: Arrays.asList メソッド

車輪を再発明しないというのはプログラミングの世界では常識だが、そのためには既に発明されているものを全て知ってしなければならない。これが意外と難しいことがある。

それはさておき、Java で List を初期化したい場合に、既に Collection があればそれを使って ArrayList のコンストラクタを呼び出すことができる。ではその Collection はどうやって初期化する? JIRO の場合は Spring Framework を使っているので、ArrayList を初期化するのは簡単なのだが、Spring を使わずに初期化する必要がある場合は、Arrays.asList を使う手がある。

Java の API リファレンスには、次のような例が出ている。

List stooges = Arrays.asList("Larry", "Moe", "Curly");

Arrays クラスというのは他にもいろいろな便利なメソッドが用意されているので、知らないと損をしてしまう。

2009年05月04日

NHK の IT 番組でやっていたメールを盗み見る話

送ったメールの内容を他のpcから盗み見るという設定で、簡単にやっていたようだが、見た感じは社内のLANでパケットモニターしているような方法のように見えた。これが簡単なようで意外と難しい。

LANのデータは二点間をパケットが流れるイメージだが、この経路以外のpcから盗み見ようとしても、最近はハブは殆どスイッチングハブなので、まず他のpcからは見えない。見るためには、スイッチングハブを特殊なものにしてモニターできるようにするか、ゲートウェイやルーターの所にトラップをかけて一網打尽にするか、そういった工夫をしなければならない。これも下手をすると大量のログが残って盗み見る側が破綻する。

以前、どうも外に出て行っているパケットが不審なので、社内から社外に出るパケットをゲートウェイになっているpcの所でトラップしたことがあったが、その時はモニター機能の付いたスイッチングハブをわざわざ購入して入れ替えて対応した。

2009年05月03日

JSF に戻す値 outcome を変えたい処理を追加する場合

someBean に action というメソッドがあるとする。このメソッドは、処理した後に OK という文字列を返す。これは JSF で状態遷移に使う outcome になる。

ここで、ある処理を追加することになった。処理の内容は殆ど action と同じなので、それを流用したいのだが、返す outcome は CONFIRM にする必要がある。そこで、someBean.action を呼び出して、戻り値を無視し、return "CONFIRM" とするようなメソッドを someBean に新たに作った。

これで目的の処理は達成しているのだが、action を呼び出したときの戻り値を無視しているという事実がどうしても気になる。こういう場合は、action の中から処理だけを取り出して別メソッドにして、action からはそれを呼び出した後に OK を返す、新しく追加するメソッドは同じように別メソッドを呼び出して CONFIRM を返す、そのように作るべきではないか?

2009年05月02日

RedHat の pc のインストール (2)

Red Hat の話の続き。結論から言って、分からない。アカウントがあるので問い合わせたらいい所だが、もう一度 update のツール(GUIの方)を起動したら、なぜかうまく接続できる。ハードウェアの情報を送ってもいいか、というような画面が出ているので、もちろんokとして、activate は無事終わったような感じである。

ただ、メッセージには、update するものはありません、というように出ている。本当なのだろうか? プリインストールしたものを購入しているのだから、update までしておいてくれてもよさそうなものだが、activation の前にそういうことができるのか?

ということで、何となく root で yum update してみたら、

Install 11 Package(s)
Update 400 Package(s)

何か大量に釣れるような。ともあれこれで最新版になったような気がする。

2009年05月01日

RedHat の pc のインストール

RedHat のインストール。プリインストールだから、特に何かしなくても動くはずと思ったら甘かった。とりあえず動いたが、まずネットワークの設定でひっかかった。DHCP が使えない環境なので、手動で設定してやらないといけない。これを設定した後で、RHN に接続しにいくはずだったが、どこにも行く気配がない。謎。

routerの設定とか見直して外に出て行けるようになったが、RHN の activation をしていない。activation をしたいのだが、これが意外と難しい。システムの update をしようとしたのだが、「アカウントは正しいが別のシステムで使っている」のようなメッセージが。謎。

顛末は次回に続く。