JBossCache on WAS (WebSphere Application Server)
Overview
WAS developers can utilize JBossCache because it does not have any JBossAS dependencies. There are several use-cases where JBossCache on WAS is benefitial.
Create a distributed, possibly transactional POJO cache that is not HttpSession or SFSB bound. JBossCache is a value-add in that it can provide access to shared resources across user sessions.
Use JBossCache as a 2nd level cache provider for Hibernate, especially if running in a WAS cluster.
Application server agnostic development. JBossCache will reduce the code required to port the app to other containers.
HowTo - Author: gdaswani
I got it working on WebSphere 5.1.1
Here's a couple of things you need to do
1) Unjar the $WAS_ROOT/lib/jmxc.jar and MAKE SURE it's unsealed (check the MANIFEST) then jar it back up..
2) Copy the necessary TreeCache Libs on $WAS_ROOT/lib/ext directory
3) Copy your TreeCache configuration file to $WAS_ROOT/classes directory
4) Create a Custom Service that initializes TreeCache and sticks it's reference on a Singleton.
Note, on WebSphere, you can't stick the TreeCache onto JNDI as it's not serializable (unlike on other servers where you can if said JNDI entry is on the local server scope). Hence, you'll have to create some sort of singleton that is initialized by the Custom Service.
As an alternative, one could copy the JrmpProxyFactory MBean to WebSphere, create a proxy to JBossCache, and
bind the proxy into JNDI.
Below is some sample code how to wrap JBossCache into a WS custom service:
import java.util.Properties; import javax.management.Notification; import javax.management.NotificationFilterSupport; import javax.management.NotificationListener; import javax.management.ObjectName; import javax.naming.InitialContext; import javax.transaction.SystemException; import javax.transaction.TransactionManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.cache.Fqn; import org.jboss.cache.PropertyConfigurator; import org.jboss.cache.TreeCache; import com.esri.infoservices.j2ee.jbosscache.exceptions.InvalidArgumentException; import com.ibm.websphere.management.AdminServiceFactory; import com.ibm.websphere.management.NotificationConstants; import com.ibm.websphere.runtime.CustomService; public class JCacheWAS51Service implements CustomService, NotificationListener { public final static String NODE_PATH = "/GlobalCache"; private final static String CACHE_INITIALIZED_KEY = "CacheInitialized"; private TreeCache treeCache = null; private Log logger = LogFactory.getLog(getClass()); private String jndiName = null; public void initialize(Properties configuration) throws Exception { String configFile = null; logger.info("JCacheWAS51Service.initialize(): starting up."); if (configuration != null && !configuration.isEmpty()) { if (logger.isDebugEnabled()) { configuration.list(System.out); } configFile = configuration.getProperty("configFile"); if (configFile == null || configFile.trim().length() == 0) { throw new InvalidArgumentException( "JCacheWAS51Service: configFile configuration property is required."); } logger .debug("JCacheWAS51Service.initialize(): Starting up TreeCache."); treeCache = new TreeCache(); PropertyConfigurator configurator = new PropertyConfigurator(); configurator.configure(treeCache, configFile); treeCache.createService(); treeCache.startService(); logger .debug("JCacheWAS51Service.initialize(): setting up filters to wait for WAS startup."); NotificationFilterSupport filter = new NotificationFilterSupport(); filter.enableType(NotificationConstants.TYPE_J2EE_STATE_RUNNING); ObjectName target = new ObjectName("WebSphere:*,type=Server"); AdminServiceFactory .getAdminService() .addNotificationListenerExtended(target, this, filter, null); logger.info("JCacheWAS51Service.initialize(): waiting."); } else { logger.debug("JCacheWAS51Service.initialize(): not configured."); } } public void shutdown() throws Exception { logger .info("JCacheWAS51Service.shutdown(): server is stopping, shutting down cache."); if (treeCache != null) { treeCache.stopService(); treeCache.destroyService(); } } public void handleNotification(Notification arg0, Object arg1) { TransactionManager transaction = null; try { logger .info("JCacheWAS51Service.handleNotification(): TreeCache, creating initial NODE_PATH [" + NODE_PATH + "]."); transaction = treeCache.getTransactionManager(); transaction.begin(); Fqn nodeName = new Fqn(NODE_PATH); Boolean initialized = (Boolean) treeCache.get(nodeName, CACHE_INITIALIZED_KEY); if (initialized == null || initialized == Boolean.FALSE) { treeCache.put(nodeName, CACHE_INITIALIZED_KEY, Boolean.TRUE); } transaction.commit(); logger .debug("JCacheWAS51Service.handleNotification: done with cache handling."); } catch (Exception error) { logger .error("JCacheWAS51Service.handleNotification: error handling transaction, message=" + error.getMessage()); try { transaction.rollback(); } catch (SystemException warn) { logger.warn(warn); } } } }
Comments