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

役に立ったらぽちっとよろしく。 人気ブログランキングへ

インチキSerializable [2009/03/01 (日)]

…前回の記事の追記に、、、間違い発見!!TypedKeyimplements Serializableとあるけど、同一性の判定がリファレンス判定(==演算子)だから、シリアライズ前後で同一性が崩れる。普通のクラスならこれでいいんだけど、キー専用クラスでこれはひどい。しかも、finalになってるからequalsメソッドのオーバライドのしようがない。

で、解決策を考えたんだけども…あんましいー案が無い…。final取って、デシリアライズ時に前と同じインスタンスの作り方をするよう個々のメソッドをオーバライドする事を考えたんだけど…。楽しようとしてそれを匿名クラスでやろうとすると、Javaの仕様的にまずい事になる*1。つまり、いちいちstaticクラス(内部クラスも可)を宣言して、SerialVersionUIDをつけて…ん?もうデシリアライズ用のメソッドいらないか、、、でもどのみち面倒…。もうぶっちゃけ振り出しに戻ってStringでいいかも…とも思うけどでもそれはそれでちょい危険だし、、、う~ん…。


さてさて!!、日本のいい言葉に、「我が振り見て人の振り直せ」という言葉がある。これは自分が失敗した時には、同じ失敗をしている人を見つけて、その人の失敗を指摘してる間に自分の失敗をうやむやにしてしまおうという、素ん晴らしい言葉だ。そう、おいら以外にもインチキSerializableを作っているライブラリを発見!!

Commons FileUpload (お世話になっております) のDiskFileItemクラスがそれだ。ファイルアップロードの場面で確認画面とかを出そうと思ったら一旦ファイルをセッションやらDB側で保存しないといけない。しかも、ユーザは結局そのファイルを使わずどっか行ってしまうかもしれない。そうなるといつ消されるとも分からないファイルが残る。セッション破棄イベントでそれらを消すにしても、ドSなユーザがファイルを沢山アップロードをしたらば、もうお終いになる。(量に制限をかけて、古いファイルを消す手もあるけど、ユーザ数が多すぎてセッション自体を使いたくない場合は本当にお手上げ) と、まぁそんなこんなで、ファイルデータの入ったDiskFileItemをビューステートに入れといてサーバリソースを節約しようとしたら、悲劇! 一時ファイルが読めない!Servletスレッドが終了したら、どっかのタイミングで一時ファイルが消されるらしい。

…まぁ当然と言えば当然なんだけど。なんでこんな当たり前に気づかなかったかと言うと、ドキュメントにimplements Serializableってあったから。そう、ドラマで言うなら、「何か変だと思ったけど信じたの!」 「できないなら最初っから出来ないって言えばいいじゃない!」 「何でウソつくの!?」 「もーいい!自分でやるわ!」 って展開の主人公になる…そうちょっと理不尽。 …ま、…おいらのケースよりはいく分ましだけど…。:-P)

*1
匿名クラスの名前の付け方はコンパイラによって違い、さらにstaticフィールドを付けられないので、serialVersionUIDも宣言できない。これではクラスの特定が出来なくなる。ちなみに、ローカルクラスと非static内部クラスも親クラスインスタンスへの暗黙フィールドの名前の付け方がコンパイラによって差があってシリアライズの障害になる。
スポンサーサイト

役に立ったらぽちっとよろしく。 人気ブログランキングへ

コメント
この記事へのコメント
コメントを投稿する

トラックバック
この記事のトラックバックURL
この記事へのトラックバック
Copyright © ふらふら技術者の日記 All Rights Reserved.
Powered by FC2 Blog
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。