OSCache 2.4.1 での変更点を見てみる

http://wiki.opensymphony.com/display/CACHE/Complete+Change+Log

変更点

バグ対応
  • [CACHE-279] - LRUCache loses entries when updated by mutliple threads.
  • [CACHE-296] - For a Cache class the cacheFlushed method is not being invoked on the CacheEntryEventListener.
  • [CACHE-297] - max-age parameter not set on ResponseContent object returned from cache when using MAX_AGE_NO_INIT
タスク
  • [CACHE-209] - Review: Handling junit failures in threads other than the main thread

ちょっと気になった変更点

[CACHE-279] - LRUCache loses entries when updated by mutliple threads.
  • 元々2.3.2の問題として挙げられたもので、2.4.1にて再現不能でクローズされてます。いいのか?
[CACHE-296] - For a Cache class the cacheFlushed method is not being invoked on the CacheEntryEventListener.
if (listeners[i] instanceof CacheEntryEventListener) {

should be:

if (listeners[i+1] instanceof CacheEntryEventListener) { 

ということで修正されているようだが、修正内容だけ見るとワークアラウンドっぽいにおいがする。ということで、ソースを見てみる。

// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {

なるほど。確かに混乱するforループですね。
リスナーが、2個単位で入ってるようですね。

おぉw

import javax.swing.event.EventListenerList;

SwingのEventListenerList使ってるw
確かに、このforループの使い方、EventListenerListのjavadocのお手本そのものですね。おいらも、Swing使ってるときはめちゃめちゃ多用していましたが、GUI使わないプログラムでSwingパッケージに依存するのはどうかと利用を控えていたのですが、、、。昔おいらがSwingを使ってたころは、javaxというパッケージが導入された直後で、これに依存するのは将来的にどうかという懸念がありました。しかし、現状を鑑みるに全く問題なしですね。なるほど。

しかし、

Object[] listeners = listenerList.getListenerList();

として、forループ内で

if (listeners[i+1] instanceof CacheEntryEventListener)

するなら、そもそも

listenerList.getListeners(CacheEntryEventListener.class);

しておけばいいんじゃないのかな? とおもいきや、getListeners は、instanceof ではなくequalsで対応なのね。なるほど。でも、それだったら独自のリスナーリストクラスを作成するのもありかな。更に、逆順で配列を辿るのであれば、それは単体で機能として切り出せるので、逆順ソートを別に切り出すのもありかも。あんまり単体テストする気ないのかな?