Hi Ivan!
On Apr 1, 2009, at 7:25 AM, [email protected] wrote:
First of all, sorry about the previous messages, with the strange
character codes. I hope this message doesn't have those in it.
Looks great, thanks!
Second, I have found the place in OpenEJB that causes the problems
for me. Please see the comments in the code (that I have added)!
public class Memoizer<K, V> implements Computable<K, V> {
private final ConcurrentMap<K, Future<V>> cache = new
ConcurrentHashMap<K, Future<V>>();
private final Computable<K, V> c;
public Memoizer(Computable<K, V> c) {
this.c = c;
}
// This method causes the NullPointerException and will
// loop forever when that happens.
public V compute(final K key) throws InterruptedException {
while (true) {
Future<V> future = cache.get(key);
// When arriving here, future will not be null.
if (future == null) {
Callable<V> eval = new Callable<V>() {
public V call() throws Exception {
return c.compute(key);
}
};
FutureTask<V> futureTask = new
FutureTask<V>(eval);
future = cache.putIfAbsent(key, futureTask);
if (future == null) {
future = futureTask;
futureTask.run();
}
}
try {
// The NullPointerException occurs when calling
// future.get()
return future.get();
} catch (ExecutionException e) {
// So, finally, we arrive here and print the
stacktrace
// and go back for another NullPointerException...
e.printStackTrace();
}
}
}
}
If the above class were to let the exception propagate out, then it
would eventually reach the WebappClassLoader.clearReferences() in
Tomcat and the clearing of static and final fields in that
particular class would be skipped and the only "problem" I would
have would be a stacktrace in the Tomcat log.
So how about it, OpenEJB people, is this fixable?
I'm guessing that the null is from the Computable c being set to
null. Trying changing the Memoizer constructor to do a null check.
Something like 'if (c == null) throw new
NullPointerException("Computable is null")'. That might flush the
issue out at a more appropriate place.
-David