If a call to DeferredHelper.invoking(...) is made with an instance/class that is final, the ThreadLocal should not contain a reference to the Deferred that was used as it will later corrupt the state of the DeferredHelper.eventually(...) call.
To resolve the issue we need to re-order the statements in the DeferredHelper.invoking(...) method.
public static <T> T invoking(Deferred<T> deferred)
{
// ensure that there are no other pending invoking calls on this thread
if (m_deferred.get() == null)
{
// FUTURE: we should raise a soft exception here if the deferred
// class is final or perhaps native as we can't proxy them.
// attempt to create a proxy of the specified object class that will record
// methods calls on the object and represent them as a deferred on a thread local
T proxy = ReflectionHelper.createProxyOf(deferred.getDeferredClass(), new DeferredMethodInteceptor());
// set the current deferred as a thread local so that
// we can "eventually" evaluate and return it.
m_deferred.set(deferred);
return proxy;
}
else
{
...
}
}
If a call to DeferredHelper.invoking(...) is made with an instance/class that is final, the ThreadLocal should not contain a reference to the Deferred that was used as it will later corrupt the state of the DeferredHelper.eventually(...) call.
To resolve the issue we need to re-order the statements in the DeferredHelper.invoking(...) method.