EJB container events in JOnASThe following describes a JOnAS service that registers an MBean listener to EJB container registration/unregistration events. These events are generated when an EJB jar file is deployed/undeployed. Handling these events allows running custom setup/cleanup code when EJBs are added or removed respectively from the EJB container. When a EJB registration event is received, the listener checks whether the event refers to a stateless session bean. If that bean implements the InitBean interface, then its InitBean.deploy() method is called. Similarly for unregistration events, the InitBean.undeploy() event is called. Thus, the InitBean remote interface is: public interface InitBean { void deploy() throws RemoteException; void undeploy() throws RemoteException } The skeleton of the service class is: public class EventService implements Service { private String name; public void init(Context ctx) throws ServiceException { jmxService = (JmxService)ServiceManager.getInstance().getService("jmx"); ejbService = (EJBService)ServiceManager.getInstance().getService("ejb"); } public void start() throws ServiceException { registerMBeanListener(); } public void stop() throws ServiceException { unregisterMBeanListener(); } public void setName(String name) { this.name = name; } public String getName() { return name; } } From the J2EE API docs: " To receive to MBeanServerNotifications, you need to be declared as listener to the javax.management.MBeanServerDelegate MBean that represents the MBeanServer". The ObjectName of the MBeanServerDelegate is: JMImplementation:type=MBeanServerDelegate And below we register a listener to events from the MBeanServerDelegate MBean MBeanServer mbeanServer; ObjectName objectName; objectName = new ObjectName("JMImplementation:type=MBeanServerDelegate"); listener = new NotificationListener() { public void handleNotification(Notification notification, Object handback) { EventService.this.handleNotification(notification, handback); }}; mbeanServer = jmxService.getJmxServer(); mbeanServer.addNotificationListener(objectName, listener, null, null); When a notification is received, the name of the entity involved is extracted and then the notification is forwarded to registration/unregistration handlers: ObjectName name; if (!(notification instanceof MBeanServerNotification)) return; name = getObjectName((MBeanServerNotification)notification); if (name == null) return; if (notification.getType().equals( MBeanServerNotification.REGISTRATION_NOTIFICATION)) handleRegistration(name); else if (notification.getType().equals( MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) handleUnregistration(name); The registration handling code loads the home interface class for the session bean. Then it calls create() on the home reference and finally deploy() on the created session bean: ClassLoader loader, threadLoader; Class remoteClass, homeClass; String jndiName; Method method; InitBean bean; loader = getClassLoader(name); if (loader == null) return; threadLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(loader); try { remoteClass = getRemoteClass(name, loader); if (remoteClass == null) return; if (!InitBean.class.isAssignableFrom(remoteClass)) return; homeClass = getHomeClass(name, loader); if (homeClass == null) return; method = homeClass.getMethod("create", new Class[]{}); if (method == null) return; jndiName = getJndiName(name); if (jndiName == null) return; bean = getBeanInstance(jndiName, method); if (bean == null) return; bean.deploy(); } finally { Thread.currentThread().setContextClassLoader(threadLoader); }
|
|