I have the following problem with an EJB 2 SessionBean when deploying in JBoss 5:
The SessionBean (called LVSKeepAliveDispatcher) requires a specific user role (called "LVSUser"), specified by
<method-permission >
<description></description>
<role-name>LVSUser</role-name>
<method >
<description></description>
<ejb-name>LVSKeepAliveDispatcher</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
in ejb-jar.xml. I now want to access this SessionBean from a Service (i.e. a class implementing the org.jboss.varia.scheduler.Schedulable interface that is then registered as a service) running inside the same JBoss instance. This is my jboss-service.xml:
<server>
<mbean code="org.jboss.varia.scheduler.Scheduler" name="lvs:service=TranslationService">
<attribute name="StartAtStartup">true</attribute>
<attribute name="SchedulableClass">de.repower.lvs.server.service.translation.TranslationService</attribute>
<attribute name="SchedulableArguments"></attribute>
<attribute name="SchedulableArgumentTypes"></attribute>
<attribute name="InitialStartDate">NOW</attribute>
<attribute name="SchedulePeriod">60000</attribute>
<attribute name="InitialRepetitions">1</attribute>
<attribute name="TimerName">jboss:service=Timer,name=TranslationServiceTimer</attribute>
<depends><mbean code="javax.management.timer.Timer" name="jboss:service=Timer,name=TranslationServiceTimer"/></depends>
<depends>jboss.j2ee:service=EJB,jndiName=de/repower/lvs/i18n/sessionbeans/LVSTranslation</depends>
</mbean>
As the service is deployed in the same vm as the session bean I want to call the session bean via the local interface, but I get a SecurityException when I try to create an instance. When instead I do a lookup of the RemoteInterface it works. This is the code inside the perform method of my service class:
public void perform(Date now, long remainingRepetitions) {
try {
final UsernamePasswordHandler handler = new UsernamePasswordHandler(USERNAME, PASSWORD);
final LoginContext lc = new LoginContext("client-login", handler);
lc.login();
// Trying to instantiate an LVSKeepAliveDispatcher via remote interface
// This part works
LVSKeepAliveDispatcher localvHome = LVSKeepAliveDispatcherUtil.getHome().create();
LOGGER.info("Successfully instantiated an LVSKeepAliveDispatcher " + localvHome.toString());
// Trying to instantiate an LVSKeepAliveDispatcherLocal via local interface
LVSKeepAliveDispatcherLocal localvLocalHome = LVSKeepAliveDispatcherUtil.getLocalHome().create();
// this code is unforunately never reached
LOGGER.info("Successfully instantiated an LVSKeepAliveDispatcherLocal " + localvLocalHome.toString());
lc.logout();
} catch (final Exception ex) {
LOGGER.error("Error: ", ex);
}
}
Exception:
2009-02-17 10:38:02,266 INFO [lvsi18n] (Timer-2) Successfully instantiated an LVSKeepAliveDispatcher de/repower/lvs/server/service/alive/sessionbeans/LVSKeepAliveDispatcher:Stateless
2009-02-17 10:38:02,297 ERROR [org.jboss.ejb.plugins.SecurityInterceptor] (Timer-2) Error in Security Interceptor
java.lang.SecurityException: Authentication exception, principal=internalSystemUser
at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityContext(SecurityInterceptor.java:321)
at org.jboss.ejb.plugins.SecurityInterceptor.process(SecurityInterceptor.java:243)
at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:205)
at org.jboss.ejb.plugins.security.PreSecurityInterceptor.process(PreSecurityInterceptor.java:136)
at org.jboss.ejb.plugins.security.PreSecurityInterceptor.invokeHome(PreSecurityInterceptor.java:88)
at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:132)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:107)
at org.jboss.ejb.SessionContainer.internalInvokeHome(SessionContainer.java:639)
at org.jboss.ejb.Container.invoke(Container.java:1046)
at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invokeHome(BaseLocalProxyFactory.java:362)
at org.jboss.ejb.plugins.local.LocalHomeProxy.invoke(LocalHomeProxy.java:133)
at $Proxy193.create(Unknown Source)
at de.repower.lvs.server.service.translation.TranslationService.perform(TranslationService.java:68)
at org.jboss.varia.scheduler.Scheduler$PojoScheduler.invoke(Scheduler.java:1267)
at org.jboss.varia.scheduler.Scheduler$BaseListener.handleNotification(Scheduler.java:1235)
at sun.reflect.GeneratedMethodAccessor281.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.mx.notification.NotificationListenerProxy.invoke(NotificationListenerProxy.java:153)
at $Proxy87.handleNotification(Unknown Source)
at javax.management.NotificationBroadcasterSupport.handleNotification(NotificationBroadcasterSupport.java:257)
at javax.management.NotificationBroadcasterSupport$SendNotifJob.run(NotificationBroadcasterSupport.java:322)
at javax.management.NotificationBroadcasterSupport$1.execute(NotificationBroadcasterSupport.java:307)
at javax.management.NotificationBroadcasterSupport.sendNotification(NotificationBroadcasterSupport.java:229)
at javax.management.timer.Timer.sendNotification(Timer.java:1234)
at javax.management.timer.Timer.notifyAlarmClock(Timer.java:1203)
at javax.management.timer.TimerAlarmClock.run(Timer.java:1286)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
To further diagnose the error I debugged through the SecurityInterceptor and found that in the first case (successful creating an instance via the remote interface) the security context "lvs-security" (which I defined in login-config.xml) is being used whereas in the second case (failure when creating an instance via the local interface) the generic security context "CLIENT-LOGIN" is being used.
This is the definition of the securit context "lvs-security" in login-config.xml:
<application-policy name = "lvs-security">
<authentication>
<login-module code = "org.jboss.security.ClientLoginModule" flag = "required">
</login-module>
<login-module code = "de.repower.lvs.security.UsersRolesLoginModule" flag = "sufficient">
</login-module>
<login-module code = "de.repower.lvs.security.login.LVSLoginModule" flag = "required">
<module-option name = "lvs-jboss-host">localhost</module-option>
<module-option name = "lvs-jboss-jndi-port">1099</module-option>
</login-module>
</authentication>
</application-policy>
I'm now kind of stuck and hope someone can give me a hint about where to further look for the cause of the problem. This worked fine in JBoss 3.2.7.
Edit:
My current workaround for this problem:
create a new container configuration in jboss.xml and remove the security interceptor stuff from this configuration
use this newly created container configuration for all my session beans that I only use locally (i.e. via local interface).