
What we are implementing in our upcoming 2.0.3 release is grid-enabled ExecutorService, where users will simply submit standard Java Runnable or Callable tasks to execute them on remote grid nodes. To user this would still look no different than using standard java.util.concurrent.ExecutorService locally, but the grid-enabled service transparently provides all the grid computing features underneath, such as fail-over, load balancing, scheduling, peer-class-loading, etc...
However, it turns out that Sun made a mistake with generics in JDK5 and decided to "fix" it in JDK6. So these methods from JDK5
invokeAll(Collection<Callable<T>> tasks)
invokeAll(Collection<Callable<T>> tasks, long timeout, TimeUnit unit)
invokeAny(Collection<Callable<T>> tasks)
invokeAny(Collection<Callable<T>> tasks, long timeout, TimeUnit unit)
now look as following in JDK 6 (note the <? extends ...> clause)
invokeAll(Collection<? extends Callable<T>> tasks)
invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
invokeAny(Collection<? extends Callable<T>> tasks)
invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
The weird thing is that Sun acknowledges the mistake (here is the bug #6267833), but what I don't like is the "JSR-166 expert group" explanation which goes as following:
...requires minor source code changes for the small set of developers who have implemented ExecutorService without inheriting the default implementations in AbstractExecutorService. The set of affected developers are developers creating sophisticated thread pool applications, putting them into the "concurrency rocket scientist" category. They will generally appreciate this change. The possible compiler error is trivial to fix in the source code.
Well, I guess GridGain dev team falls into "concurrency rocket scientist" category, as we really do need to implement ExecutorService and we cannot use AbstractExecutorService just because it was not really designed for reuse in the first place.
So here is my beef with SUN:
1) Sun messed up with generics so badly, that even their own developers don't understand how to use them. On top of that, why in the world do I need to specify <? extends SomeInterface> for generics? What else am I going to do with an interface other than *extend* it. Well... I guess I can stare at it, but I don't think it counts.
2) The JSR166 expert group decided that that they are the smartest bunch in the world, and that people who use JDK for purposes other than writing simple if statements and for loops are really hard to come by. So, they simply decided that it is good enough for 95% of JAVA users, and the other 5% will appreciate their "rocket science" fix that brilliantly breaks compilation.
3) They decided to fix it and break source code backward compatibility while there was a clear work around described in the same bug. People could still do the following without any warnings in the code:
service.invokeAll(Collections.<Callable<Object>>singleton(x));
Now, this is not fatal to us in any way. Since binary compatibility is still preserved, most of our users who just use GridGain binaries will never notice. But being an open source company, we ship with both, binaries and source code, and now our source code will not compile out of the box on both, JDK 1.5 and 1.6, which I find really annoying.
View comments