JBoss.orgCommunity Documentation
When used in a standalone Java program, all that needs to be done is to instantiate the cache using the
CacheFactory
and a
Configuration
instance or an XML file, as discussed
in the
User API
and
Configuration
chapters.
The same techniques can be used when an application running in an application
server wishes to programatically deploy a cache rather than relying on an application server's
deployment features. An example of this would be
a webapp deploying a cache via a
javax.servlet.ServletContextListener
.
After creation, you could share your cache instance among different application components either by using an IOC container such as Spring, JBoss Microcontainer, etc., or by binding it to JNDI, or simply holding a static reference to the cache.
If, after deploying your cache you wish to expose a management interface to it in JMX, see the section on Programatic Registration in JMX.
For detailed information on how to deploy JBoss Cache instances this way, please check section "11.2. Deploying Your Own JBoss Cache Instance" and more specifically, section "11.2.3. Deployment Via a -jboss-beans.xml File" in the JBoss Application Server 5 Clustering Guide.
Although access to cache instances bound to JNDI is not possible, JBoss Application Server 5 binds a CacheManager to JNDI which can be looked up and from where cache instances can be retrieved. Further detailed information can be found in section "11.2.1. Deployment Via the CacheManager Service" in the JBoss Application Server 5 Clustering Guide.
JBoss Cache includes JMX MBeans to expose cache functionality and provide statistics that can be used to analyze cache operations. JBoss Cache can also broadcast cache events as MBean notifications for handling via JMX monitoring tools.
JBoss Cache provides an MBean that can be registered with your environments JMX server to allow access
to the cache instance via JMX. This MBean is the
org.jboss.cache.jmx.CacheJmxWrapper
.
It is a StandardMBean, so its MBean interface is org.jboss.cache.jmx.CacheJmxWrapperMBean
.
This MBean can be used to:
Cache
.
Cache
.
See the CacheJmxWrapperMBean
javadoc for more details.
If a CacheJmxWrapper
is registered, JBoss Cache also provides MBeans
for several other internal components and subsystems. These MBeans are used to capture and expose
statistics related to the subsystems they represent. They are hierarchically associated with the
CacheJmxWrapper
MBean and have service names that reflect this relationship. For
example, a replication interceptor MBean for the jboss.cache:service=TomcatClusteringCache
instance will be accessible through the service named
jboss.cache:service=TomcatClusteringCache,cache-interceptor=ReplicationInterceptor
.
The best way to ensure the CacheJmxWrapper
is registered in JMX depends on how you are
deploying your cache.
Simplest way to do this is to create your Cache
and pass it to the
JmxRegistrationManager
constructor.
CacheFactory factory = new DefaultCacheFactory();
// Build but don't start the cache
// (although it would work OK if we started it)
Cache cache = factory.createCache("cache-configuration.xml");
MBeanServer server = getMBeanServer(); // however you do it
ObjectName on = new ObjectName("jboss.cache:service=Cache");
JmxRegistrationManager jmxManager = new JmxRegistrationManager(server, cache, on);
jmxManager.registerAllMBeans();
... use the cache
... on application shutdown
jmxManager.unregisterAllMBeans();
cache.stop();
CacheJmxWrapper
is a POJO, so the microcontainer has no problem creating one. The
trick is getting it to register your bean in JMX. This can be done by specifying the
org.jboss.aop.microcontainer.aspects.jmx.JMX
annotation on the CacheJmxWrapper
bean:
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
<!-- First we create a Configuration object for the cache -->
<bean name="ExampleCacheConfig"
class="org.jboss.cache.config.Configuration">
... build up the Configuration
</bean>
<!-- Factory to build the Cache. -->
<bean name="DefaultCacheFactory" class="org.jboss.cache.DefaultCacheFactory">
<constructor factoryClass="org.jboss.cache.DefaultCacheFactory"
factoryMethod="getInstance" />
</bean>
<!-- The cache itself -->
<bean name="ExampleCache" class="org.jboss.cache.CacheImpl">
<constructor factoryMethod="createnewInstance">
<factory bean="DefaultCacheFactory"/>
<parameter><inject bean="ExampleCacheConfig"/></parameter>
<parameter>false</parameter>
</constructor>
</bean>
<!-- JMX Management -->
<bean name="ExampleCacheJmxWrapper" class="org.jboss.cache.jmx.CacheJmxWrapper">
<annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.cache:service=ExampleTreeCache",
exposedInterface=org.jboss.cache.jmx.CacheJmxWrapperMBean.class,
registerDirectly=true)</annotation>
<constructor>
<parameter><inject bean="ExampleCache"/></parameter>
</constructor>
</bean>
</deployment>
As discussed in the Programatic Registration
section, CacheJmxWrapper
can do the work of building, creating and starting the
Cache
if it is provided with a Configuration
. With the
microcontainer, this is the preferred approach, as it saves the boilerplate XML
needed to create the CacheFactory
.
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
<!-- First we create a Configuration object for the cache -->
<bean name="ExampleCacheConfig"
class="org.jboss.cache.config.Configuration">
... build up the Configuration
</bean>
<bean name="ExampleCache" class="org.jboss.cache.jmx.CacheJmxWrapper">
<annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.cache:service=ExampleTreeCache",
exposedInterface=org.jboss.cache.jmx.CacheJmxWrapperMBean.class,
registerDirectly=true)</annotation>
<constructor>
<parameter><inject bean="ExampleCacheConfig"/></parameter>
</constructor>
</bean>
</deployment>
JBoss Cache captures statistics in its interceptors and various other components, and exposes these
statistics through a set of MBeans. Gathering of statistics is enabled by default; this can be disabled for
a specific cache instance through the Configuration.setExposeManagementStatistics()
setter. Note that the majority of the statistics are provided by the CacheMgmtInterceptor
,
so this MBean is the most significant in this regard. If you want to disable all statistics for performance
reasons, you set Configuration.setExposeManagementStatistics(false)
and this will
prevent the CacheMgmtInterceptor
from being included in the cache's interceptor stack
when the cache is started.
If a CacheJmxWrapper
is registered with JMX, the wrapper also ensures that
an MBean is registered in JMX for each interceptor and component that exposes statistics.
[1].
Management tools can then access those MBeans to examine the statistics. See the section in the
JMX Reference chapter
pertaining to the statistics that are made available via JMX.
JBoss Cache users can register a listener to receive cache events described earlier in the
User API
chapter. Users can alternatively utilize the cache's management information infrastructure to receive these
events via JMX notifications. Cache events are accessible as notifications by registering a
NotificationListener
for the CacheJmxWrapper
.
See the section in the JMX Reference chapter
pertaining to JMX notifications for a list of notifications that can be received through the
CacheJmxWrapper
.
The following is an example of how to programmatically receive cache notifications when running in a JBoss AS environment. In this example, the client uses a filter to specify which events are of interest.
MyListener listener = new MyListener();
NotificationFilterSupport filter = null;
// get reference to MBean server
Context ic = new InitialContext();
MBeanServerConnection server = (MBeanServerConnection)ic.lookup("jmx/invoker/RMIAdaptor");
// get reference to CacheMgmtInterceptor MBean
String cache_service = "jboss.cache:service=TomcatClusteringCache";
ObjectName mgmt_name = new ObjectName(cache_service);
// configure a filter to only receive node created and removed events
filter = new NotificationFilterSupport();
filter.disableAllTypes();
filter.enableType(CacheNotificationBroadcaster.NOTIF_NODE_CREATED);
filter.enableType(CacheNotificationBroadcaster.NOTIF_NODE_REMOVED);
// register the listener with a filter
// leave the filter null to receive all cache events
server.addNotificationListener(mgmt_name, listener, filter, null);
// ...
// on completion of processing, unregister the listener
server.removeNotificationListener(mgmt_name, listener, filter, null);
The following is the simple notification listener implementation used in the previous example.
private class MyListener implements NotificationListener, Serializable
{
public void handleNotification(Notification notification, Object handback)
{
String message = notification.getMessage();
String type = notification.getType();
Object userData = notification.getUserData();
System.out.println(type + ": " + message);
if (userData == null)
{
System.out.println("notification data is null");
}
else if (userData instanceof String)
{
System.out.println("notification data: " + (String) userData);
}
else if (userData instanceof Object[])
{
Object[] ud = (Object[]) userData;
for (Object data : ud)
{
System.out.println("notification data: " + data.toString());
}
}
else
{
System.out.println("notification data class: " + userData.getClass().getName());
}
}
}
Note that the JBoss Cache management implementation only listens to cache events after a client registers to receive MBean notifications. As soon as no clients are registered for notifications, the MBean will remove itself as a cache listener.
JBoss Cache MBeans are easily accessed when running cache instances in an application server that provides an MBean server interface such as JBoss JMX Console. Refer to your server documentation for instructions on how to access MBeans running in a server's MBean container.
In addition, though, JBoss Cache MBeans are also accessible when running in a non-server environment using
your JDK's jconsole
tool. When running a standalone cache outside of an application server,
you can access the cache's MBeans as follows.
-Dcom.sun.management.jmxremote
when starting the JVM where the cache will run.
jconsole
utility, located in your JDK's
/bin
directory.
Note that the jconsole
utility will automatically register as a listener for cache
notifications when connected to a JVM running JBoss Cache instances.
[1]
Note that if the
CacheJmxWrapper
is not registered in JMX, the
interceptor MBeans will not be registered either. The JBoss Cache 1.4 releases
included code that would try to "discover" an
MBeanServer
and
automatically register the interceptor MBeans with it. For JBoss Cache 2.x we decided
that this sort of "discovery" of the JMX environment was beyond the proper scope of
a caching library, so we removed this functionality.