[
https://issues.jboss.org/browse/WFLY-5537?page=com.atlassian.jira.plugin....
]
Yeray Santana Borges commented on WFLY-5537:
--------------------------------------------
I have been working in this issue, I haven't finished yet because before create a PR,
I would like to get some feedback from someone with more knowledge in this module.
Following the description from [~nmoelholm] and based on my tests and code checks, the
problem is that there is that ContainerManagedConcurrencyInterceptor only knows about the
mapping methods of a single view.
Mapping methods are stored in viewMethodToComponentMethodMap variable in
ContainerManagedConcurrencyInterceptor:51.
Since the interceptor has just one map, if the method invoked belongs to a view different
than the one which has initialized the viewMethodToComponentMethodMap for the current
ContainerManagedConcurrencyInterceptor intance, then the server gets the wrong type in
SingletonComponent:159, because the method name used is not mapped in the
viewMethodToComponentMethodMap.
So, it seems it is needed an access to all existing viewMethodToComponentMethodMap created
for each view in ContainerManagedConcurrencyInterceptor.
How?, I have used the own SingletonComponent to store them as proposal, but it looks a
little hack from my point of view.
With that fix, ContainerManagedConcurrencyInterceptor is able always to found any method
mapping and the problem for the wrong Lock is resolved.
SingletonComponent instance is created once all views has been already initialized, each
view with its own copy of viewMethodToComponentMethodMap.
My question is, does it seem to be quite hacking to use the SingletonComponent for that
purposed? If this approach is incorrect, any suggestions?
The changes are not finished yet, if the proposal is correct, then the instance variable
viewMethodToComponentMethodMap is not longer needed in the interceptor because using the
SingletonComponent, the interceptor can access to the viewMethodToComponentMethodMap of
each view and then avoid the locking problem.
Changes are available in this topic branch:
https://github.com/yersan/wildfly/tree/bugs/WFLY-5537
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 )
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)