]
Martin Kamp Jensen commented on WFLY-5537:
------------------------------------------
I can reproduce this on WildFly 10.0.0.Final.
Singleton EJBs with multiple views does not honor Lock semantics
----------------------------------------------------------------
Key: WFLY-5537
URL:
https://issues.jboss.org/browse/WFLY-5537
Project: WildFly
Issue Type: Bug
Components: EJB
Affects Versions: 10.0.0.CR2
Environment: 10.0.0.CR2
Reporter: Nicky Mølholm
Labels: ejb, interceptor, singleton
Upon method invocations to Singleton EJBs with multiple views... the
*ContainerManagedConcurrencyInterceptor* randomly selects a wrong Lock (READ / WRITE).
Here is an example:
{code:java}
@Singleton
@Lock(LockType.READ)
@Local({ GreeterSayMyName.class, GreeterSayHello.class })
public class GreeterBean implements GreeterSayMyName, GreeterSayHello {
@EJB
GreeterSayMyName myself;
@Override
public String sayHello() {
return "hello from " + myself.sayMyName();
}
@Override
public String sayMyName() {
return "The Greeter";
}
}
public interface GreeterSayHello {
String sayHello();
}
public interface GreeterSayMyName {
String sayMyName();
}
{code}
Sometimes (randomly) invoking the 'sayHello' method on this example EJB causes
lock upgrade exceptions. They look like this:
{noformat}
13:14:10,436 ERROR [f2PtkwmdRgaoHCdnZ7Vurg] [anonymous] [org.jboss.as.ejb3.invocation]
(default task-5 f2PtkwmdRgaoHCdnZ7Vurg) WFLYEJB0034: EJB Invocation failed on component
GreeterBean for method public abstract java.lang.String
hello.world.GreeterSayHello.sayHello(): javax.ejb.IllegalLoopbackException: WFLYEJB0238:
EJB 3.1 PFD2 4.8.5.1.1 upgrading from read to write lock is not allowed
at
org.jboss.as.ejb3.concurrency.EJBReadWriteLock.checkLoopback(EJBReadWriteLock.java:232)
at org.jboss.as.ejb3.concurrency.EJBReadWriteLock.access$300(EJBReadWriteLock.java:40)
{noformat}
This happens completely randomly.
The problem is that the interceptor only knows about one of the views' methods. At
deployment time the ViewService will start the views concurrently - and the
interceptorfactory only adds an interceptor instance to the interceptor context if one
does not already exist.
When the exception does NOT occur -then there is still a problem (although not visible
from the code): A WRITE lock is selected - even though , given the above code, it should
never ever be possible. So in fact - the issue , in that case, does not cause an
exception because .... it already has the WRITE lock.
( When the exception occurs ...then it is because the sayHello() invocation resulted in a
READ lock ... and the reentrant invocation caused a WRITE lock to be selected by the
interceptor ... but as this is not allowed, it results in a horrible exception )