Let me start with some background. Last few days I spent with profiling JBoss (5.1.0 with EJB plugin 1.0.19) and fixing our performance problems. We develop BPM solution based on standard J2EE technologies (JPA, EJB, JSF, etc) and we have a lot of tests set up. These tests runs on regular basis, every night on each of 4 application servers - Glassfish, Websphere, Weblogic, JBoss. First three servers performs quite well, the times are around 90 minutes. However JBoss never do it in less than 5 hours.
Our application use EJBs heavily, so one call from web interface may result in more than 100 underlying ejb calls (I don't know how many exactly). I am not here to judge, whether this is good pattern or not. As I said I end up profiling JBoss (not our application) and realized few things:
Most of the time is spent in these methods:
org.jboss.ejb3.security.RoleBasedAuthorizationInterceptorv2.invoke
org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke
These are interceptors around ejbs, which should authenticate caller and process any security contraints and ensure that caller has permission to invoke target method. Now the problem is we don't use standard ejb security at all - therefore by default all users are permitted to call any method. That's why I would expect that method org.jboss.ejb3.security.RoleBasedAuthorizationInterceptorv2.invoke should just return or something equivalent. However, apparently it does perform some work.
After running our performance tests on jboss, I realized that there is lot of problems and one request often take more than 20 seconds (sometimes even 4 minutes). On the other application servers it take around 2 seconds. Pretty bad. Moreover, my profiler tool showed me that there is lot of threads spending their time blocked in mentioned methods.
To sum it up, the cause of the performance problem is in authorization code, which shouldn't even be invoked, since we don't have any restrictions on our ejb methods.
The problem as I found out is that with every(!) ejb invocation, ClassLoader.loadClass(String) is called. This is a sample trace (it is called also in other places):
org.jboss.ejb3.security.RoleBasedAuthorizationInterceptorv2.invoke
SecurityHelperFactory.getEJBAuthorizationHelper
SecurityActions.loadClass
ClassLoader.loadClass
If you check source of ClassLoader.loadClass(String), you can see that ClassLoader.loadClass(String,boolean) is called and this method is synchronized, i.e results in block other threads calling it before the current thread leaves.
So I have 3 questions:
1. Is it necessary to use ClassLoader.loadClass method? Why don't you use Class.forName() instead, which is (as far as I know) non-blocking?
2. Why don't you just skip authorization of method if it has PermitAll annotation (or there is no annotation at all)
3. Can I somehow turn off RoleBasedAuthorizationInterceptorv2?