# Frequently Asked Questions About JBossCache

### Ben Wang

`<ben.wang@jboss.com>`

### Bela Ban

`<bela@jboss.com>`

August, 2004

This is frequently asked questions regarding to JBossCache.

### 1. General Information

Q: | What is JBossCache?

A:

JBossCache is a replicated and transactional cache. It is replicated since multiple JBossCache instances can be distributed and the data be replicated across the whole group. It is transactional because a user can configure a JTA transaction manager and make the cache operation transactional. Note that the cache can also be run without any replication, this is the local mode.

Currently, it consists of two components: `TreeCache` and `TreeCacheAop`. TreeCache is a tree-structured cache that provides replication and transaction context, while TreeCacheAop extends the functionality of TreeCache but behaves as a true object cache providing transparent object mapping into internal cache.

Q: | Who are the JBossCache developers?
A: | JBossCache has been developed by Bela Ban, Ben Wang, and Harald Gliebe. Currently, Bela is the overall lead while Ben leads JBossCacheAop.
Q: | What is the license for JBossCache?
A: | JBossCache is licensed under LGPL.
Q: | Where can I download the package?
A: | You can either obtain it from JBoss cvs repository in SourceForge.net, or the standalone package also in SourceForge.net.
Q: | How do I build the JBossCache myself from cvs?
A: | You will need to get jboss-head first from sourceforge.net using anonymous cvs. After doing a full build of JBoss, if you want to build the library under JBoss, do `sh build.sh`. This will produce `jboss-cache.jar`. Or if you want to build the standalone package, do `sh build.sh dist` this will produce `jboss-cache-dist.zip.`
Q: | What JVM is supported by JBossCache?
A: | JBossCache has been tested and supported on JDK1.4. On jboss-3.2 cvs tree, it also compiles on JDK1.3, but there is no official support for it though.
Q: | Can I run JBossCache outside of JBoss Application Server?

A:

Of course! JBossCache comes with two flavors:

- Integrated with JBoss server as a MBean service.

- As a standalone that can run outside of JBoss server such as under Weblogic or Websphere. Of course, it can also run under a standalone Java process (i.e., outside J2EE context).

Q: | Where can I report bugs or problems?
A: | Please report any bugs or problems to JBossCache forum.

### 2. JBossCache in general and TreeCache

Q: | How do I deploy JBossCache as a MBean service?
A: | To deploy JBossCache as a MBean inside JBoss, you can copy the configuration xml file over to the `deploy` directory (from `all` configuration whereby the necessary jars are present). Under the standalone package `etc/META-INF` directory , there are example configuration files for different cache modes that can be used to deploy JBossCache as well.
Q: | How do I know if my JBossCache MBean has been deployed?
A: | To verify that your JBossCache MBean is deployed correctly, you can first check the log output under the command console. Next you can verify it from JBoss JMX console. Look for `jboss.cache` domain.
Q: | Can I run JBossCache on 3.2 releases?
A: | Yes. The JBossCache source code is also up to date on the jboss-3.2 cvs branch. However, only TreeCache is supported there since JBossAop lives only under jboss-head.
Q: | Can TreeCache run as a second level cache inside Hibernate?
A: | Yes. Since Hibernate 2.1 release, you can configure it to use JBossCache (namely, TreeCache) as a second level cache. For details, see Hibernate documentation.
Q: | How can I configure JBossCache?
A: | You can configure the JBossCache through a configuration xml file. Or you can set it programatically through its get/set methods. Check with the documenation for both examples.
Q: | In the configuration xml file, there are tags such as `class`, `MBean`, etc. What are these?
A: | These are tags for deploying JBossCache as a JBoss MBean service. For reason of compatibility, we have kept them in the standalone package as well, specifically, the `MBean` tag. If you run in standalone mode, JBossCache will ignore these elements.
Q: | What is the difference between the different cache modes?

A:

JBossCache has three different cache modes, i.e., `LOCAL`, `REPL_SYNC`, and `REPL_ASYNC`. If you want to run JBossCache as a single instance, then you should set the cache mode to `LOCAL` so that it won't invoke replication layer. If you want to have synchronous replication among different JBossCache instances, you set it to`REPL_SYNC`. Finally, for asynchronous replication, use `AYSNC_REPL`.

Note that `ASYNC_REPL` is non-blocking. This can be useful when you want to have another JBossCache serving as a mirror or backup.

Q: | How does JBossCache's replication mechanism work?

A:

JBossCache leverage JGroups as a replication layer. A user can configure the cluster of JBossCache instances by sharing the same cluster name (`cluster name`). There is also an option of whether to populate the cache data upon starting a new instance in the `ClusterConfig` attribute.

Note that once all instances join the same replication group, every replication change is propagated to all participating members. There is no mechanism for sub-partitioning where some replication can be done within only a subset of members. This is in our to do list.

Q: | Why don't I see the MBean interface file in the JBossCache source?
A: | JBossCache uses xdoclet tag to generate the MBean class automatically. Check for example, `TreeCache.java` for `@jmx-managed` tag.
Q: | If I have the need for different treecache properties (e.g., CacheMode and IsolationLevel), do I simply need to create multiple treecache instances with the appropriate configuration?
A: | Yes. All the above mentioned properties are per cache instance. Therefore you will need a separate JBossCache instance.
Q: | Does the TreeCache config `ClusterName` have any relation to the JBoss cluster `PartitionName`?
A: | Yes. They are both JGroups group name. Besides the notion of channel is JGroups, it also can partition the channel into different group names.
Q: | When using multiple JGroups based components [cluster-service.xml, treecache (multiple instances)], what is the correct/valid way to configure those components to make sure my multicast addresses don't conflict?
A: | There are two parameters to consider: multicast address (plus port) and the group name. At minimum, you will have to run components on different group name. But whether to run them on the same channel depends upon whether the communication performance is critical for you or not. If it is, then it'd be the best to run them on different channels.
Q: | Does JBossCache currently supports cache persistence storage?
A: | Yes. Starting with release 1.1, JBossCache has a CacheLoader interface that supports the cache persistency. See below.
Q: | Is JBossCache thread safe?
A: | Yes. It is.
Q: | Does JBossCache support XA (2PC) transaction now?
A: | No, although it is also on our to do list. Our internal implementation does use a similar 2PC procedure to coordinate transaction among different instances.
Q: | What kind of TransactionManager is supported by JBossCache?
A: | JBossCache supports any TransactionManager that is JTA compliant such as JBossTM. A user can configure the transaction manager through the configuration xml setting. JBossCache also has a built in dummy transaction manager (`org.jboss.cache.tm.DummyTransactionManager`) for testing purpose only.
Q: | How do I setup the cache to be transactional?

A:

You either use the default (JBoss) TransactionManager to run JBossCache inside JBoss, or you have to implement the `TransactionManagerLookup` interface, and return an instance of your javax.transaction.TransactionManager. The configuration property `TransactionManagerLookupClass` defines the class to be used by the cache to fetch a reference to a TransactionManager. It is trivial to implement this class to support other TransactionManagers. Once this attribute is specified, the cache will look up the transaction context from this transaction manager.

For the client code, here is a snippet to start and commit a transaction:

    tx = (UserTransaction)new InitialContext(prop).lookup("UserTransaction");
    tree = new TreeCache();
    config = new PropertyConfigurator();
    config.configure(tree, "META-INF/replSync-service.xml");

    tx.begin()
    tree.put(fqn, key, value);
    tx.commit();

Q: | How do I control the cache locking level?

A:

JBossCache let you control the cache locking level through the transaction isolation level. This is configured through the attribute `IsolationLevel`. Currently, JBossCache employs pessimistic locking internally. And the transaction isolation level from the pessimist locking corresponds to JDBC isolation levels, namely, `NONE`, `READ_UNCOMMITTED`, `READ_COMMITTED`, `REPEATABLE_READ`, and `SERIALIZABLE`. For details, please refer to the user manual.

Q: | Can I monitor and manage the JBossCache?
A: | If you are running JBossCache as a MBean service inside JBoss, you can monitor and manage through the jmx console. We plan to add more attributes such as cache hit/miss numbers in the future release.
Q: | Does JBossCache support partitioning?
A: | Not right now. JBossCache does not support partitioning that a user can configure to have different set of data residing on different cache instances while still participating as a replication group.
Q: | Does JBosCache have concept of application classloading inside, say, a J2EE container?

A:

Classloading is used widely inside J2EE container. For example, a web application may require a new classloader to scope a specific version of the user library. Unfortunately, JBossCache (or cache system in general) is agnostic to the classloader. In general, there are two problems involved:

- Object instance created by thread 1 and will be accessed by thread 2 (with two different classloaders). JBossCache has no notion of different class loaders involved. As a result, you will have a `ClassCastException`.

- Object instance stored in cache1 and is replicated to cache2. As a result, the instance in cache2 is created by the system classloader. Now, a user thread in cache2 can't access it since the classloader may be different from the system one.

To solve these issues, the only solution (that we know) is to cache "serialized" byte code and only de-serialize it during every object get (and this will be expensive!). That is, during put operation, the object instance will be serialized and therefore can be replicated safely. However, the performance penalty of this approach is quite severe so in general another local in-vm version will need to be used as a "near-line" cache.

JBoss has a utility class called `MarshalledValue` that wraps around the serialized object. Here is a code snippet that illustrates how you can create a wrapper around JBossCache to handle the classloader issue:

    import org.jboss.invocation.MarshalledValue;

    public class CacheService {
       private TreeCache cache_;

       public object get(Fqn fqn, String key) {
          return getUnMarshalledValue(cache_.get(fqn, key));
       }

       public object set(Fqn fqn, String key, Object value) {
          cache_.put(fqn, key, getMarshalledValue(value));
          return value; // only if successful
       }

    ...

       private Object getUnMarshalledValue(object value) {
          // assuming we use the calling thread context classloader
          return ((MarshalledValue)value).get();
       }

       private Object getMarshalledValue(Object value) {
          return new MarshalledValue(value);
       }
    }

### 3. TreeCacheAop

Q: | What is TreeCacheAop?

A:

TreeCacheAop (currently implemented as a sub-class of TreeCache) is a replicated and transactional "object-oriented" cache. By "object-oriented", we mean that the cache: 1) automatically manages object mapping and relationship for a client under both local and replicated cache mode, 2) provides support for inheritance relationship between "advised" POJOs. By leveraging the dynamic AOP in JBossAop, it is able to map a complex object into the cache store, preserve and manage the object relationship behind the scene. During replication mode, it performs fine-granularity (i.e., on a per-field basis) update, and thus has the potential to boost cache performance and minimize network traffic.

From a user perspective, once the object is managed by the cache, all cache operations are transparent. Therefore, all the usual in-VM POJO method semantics are still preserved, providing ease of use. For example, if a POJO has been put in TreeCacheAop (by calling putObject, for example), then any get/set method will be intercepted by TreeCacheAop to provide the data from the cache.

Q: | Does TreeCacheAop have all the functional capabilities of TreeCache?
A: | Yes. TreeCacheAop extends TreeCache so it has all the same features TreeCache such as cache mode, transaction isolation level, and eviction policy.
Q: | What is the difference between TreeCache and TreeCacheAop?

A:

Think of TreeCacheAop as a TreeCache on steroid. :-) Seriously, both are cache store. However, while TreeCache only provides pure object reference storage (e.g., `put(FQN fqn, Objecy key, Object value)`), TreeCacheAop goes behind that and performs object mapping and relationship management for a user behind the scene. As a result, if you have a complex object systems that you would like to cache, you can have TreeCacheAop manages for you. You simply treat your object systems as they are residing in-memory, e.g., use your regular POJO methods without worrying about cache management. Furthermore, this is true in replication mode as well.

Q: | Can I pre-compile the aop classes such that I don't need to use the system classloader and jboss-aop configuration xml?

A:

Yes. The latest versions of JBossCache has a per-compiler option called `aopc`. You can use this option to pre-compile your "advised" POJO. Once the classes have been byte code generated, it can be treated as regular class files, i.e., you will not need to include any `jboss-aop.xml` that specifies the advisable POJO and to specify the JBossAop system class loader.

For an example of how to use `aopc`, please see the `build.xml` in the standalone package.

Q: | What's in the `jboss-aop.xml` configuration?

A:

In `jboss-aop.xml`, you declare your POJO (e.g., `Person` to be "prepared", a JBOssAop term to denote that the object will be "advised" by the system. After this declaration, JBossAop will invoke any interceptor that associates with this POJO. TreeCacheAop will dynamically add an `org.jboss.cache.aop.CacheInterceptor` to this POJO to perform object mapping and relationship management.

Note that to add your POJO, you should declare all the fields will be "advised" as in the example.

Q: | Is it possible to store the same object multiple time but with different paths? Like /foo/byName and /foo/byId ?
A: | Yes, you can use TreeCacheAop to do that. It supports the notion of object reference.
Q: | Do I need to declare all my objects "prepare" in `jboss-aop.xml`?
A: | Not necessarily. If there is some objects that you don't need the cache to manage it for you, you can leave it out of the declaration. The cache will treat this object as a "primitive" type. However, the object will need to implement `Serializable` interface though.
Q: | How do I use `List`, `Set`, and `Map` dynamic proxy?

A:

TreeCacheAop supports classes extends from `List`, `Set`, and `Map` without users to declare it "advised". It is done via a dynamic proxy. Here is a code snippet to use an `ArrayList` class.

    ArrayList list = new ArrayList();
    list.add("first");

    cache.putObject("/list/test", list);
    list.add("second"); // Won't work since AOP intercept the dynamic proxy not the original POJO.

    ArrayList myList = (List)cache.getObject("/list/test"); // we are getting a dynamic proxy instead
    myList.add("second");  // it works now
    myList.add("third");
    myList.remove("third");

### 4. Eviction Policy

Q: | Does JBossCache support eviction policy?
A: | Yes. JBossCache currently implements a LRU eviction policy for both TreeCache (`org.jboss.cache.eviction.LRUPolicy`) and TreeCacheAop (`org.jboss.cache.eviction.AopLRUPolicy`). Users can also plug in their own eviction policy algorithms. See user manual for details.
Q: | Why can't I use `org.jboss.cache.eviction.LRUPolicy` for TreeCacheAop as well?
A: | For TreeCacheAop, you will need to use `org.jboss.cache.eviction.AopLRUPolicy`) because AOP has its eviction algorithm, although is LRU but has totally different notion of an "object", for example.
Q: | Does JBossCache's implemented LRU eviction policy operates in replication mode?

A:

Yes and no. :-)

The LRU policy only operates in local mode. That is, nodes that are only evicted locally. This may cause the cache contents not to be synchronized temporarily. But when a user tries to obtain a cache content of an evicted node and finds out that is null (e.g., get returns null), it should get it from other data source and re-populate the data in the cache. During this moment, the node content will be propagated and the cache content will be in sync.

However, you still can run eviction policy with cache mode set to either `REPL_SYNC` or `REPL_ASYNC`. Depends on your use case, you can set multiple cache instances to have their own eviction policy (of which is operated locally) or just have selected instance with eviction policy activated.

Also note that, when the cache persistence layer is implemented in the next release, an locally evicted node can also be persisted to the backend store.

Q: | Does JBossCache support `Region`?

A:

Yes. JBossCache has the notion of region where a user can configure the eviction policy parameters (e.g., `maxNodes` or `timeToIdelSeconds` )

A region in JBossCache denotes a portion of tree hierarchy, e.g., a fully qualified name (`FQN`). For example, a user can define `/org/jboss` and `/org/foocom` as two separate regions. But note that you can configure the region programatically now, i.e., everything has to be configured through the xml file.

Q: | What are the `EvictionPolicyConfig` tag parameters for `org.jboss.cache.eviction.LRUPolicy`?

A:

They are:

Table 1. Parameters

wakeUpIntervalInSeconds | Interval where the clean up thread wakes to process the sitting queue and sweep away the old data.
region | A area where each eviction policy parameters are specified. Note that it needs a minimum of `/_default` region.
maxNodes | Max number of nodes allowed in the eviction queue. 0 means no limit.
timeToIdleInSeconds | Age (in seconds) for the node to be evicted in the queue. 0 denotes no limit.

Q: | I have turned on the eviction policy, why do I still get "out of memeory" (OOM) exception?

A:

OOM can happen when the speed of cache access exceeds the speed of eviction policy handling timer. Eviction policy handler will wake up every `wakeUpIntervalInSeconds` seconds to process the eviction event queue. And the queue size is fixed at 20000 now. So when the queue size is full, it will create a backlog and cause OOM to happen unless the eviction timer catches up. To address this problem, in addition to increase the VM heap size, you can also reduce the `wakeUpIntervaleInSeconds` so the timer thread processes the queue more frequently.

We will also externalize the queue size so it will be configurable in the next release.

### 5. CacheLoader

Q: | What is a CacheLoader ?

A:

A CacheLoader is the connection of JBossCache to a (persistent) data store. The CacheLoader is called by JBossCache to fetch data from a store when that data is not in the cache, and when modifications are made to data in the cache the CacheLoader is called to store those modifications back to the store.

In conjunction with eviction policies, JBossCache with a CacheLoader allows a user to maintain a bounded cache for a large backend datastore. Frequently used data is fetched from the datastore into the cache, and the least used data is evicted, in order to provide fast access to frequently accessed data. This is all configured through XML, and the programmer doesn't have to take care of loading and eviction.

JBossCache currently (July 2004) ships with 2 CacheLoader implementations:

- FileCacheLoader: this implementation uses the file system to store and retrieve data. JBossCache nodes are mapped to directories, subnodes to subdirectories etc. Attributes of a node are mapped to a file `data` inside the directory.

- BdbjeCacheLoader: this implementation is based on the Sleepycat Java Edition database, a fast and efficient transactional database. It uses a single file for the entire store. Note that if you use Sleepycat's CacheLoader with JBossCache, and ship your product, you have to acquire a commercial license from Sleepycat, see http://www.sleepycat.com/jeforjbosscache for details.

Q: | Are there other CacheLoaders ?
A: | We plan to write a DB CacheLoader, using either JDBC, or an O/R mapper such as Hibernate. Once in place, JBossCache will be able to interface with relational databases.
Q: | Can I write my own CacheLoader ?
A: | Yes. A CacheLoader is a class implementing `org.jboss.cache.loader.CacheLoader`. It is configured via the XML file (see JBossCache and Tutorial documentation).
Q: | Does a CacheLoader have to use a persistent store ?
A: | No, a CacheLoader could for example fetch (and possibly store) its data from a webdav-capable webserver. Another example is a caching proxy server, which fetches contents from the web. Note that an implementation of CacheLoader may not implement the 'store' functionality in this case, but just the 'load' functionality.
Q: | What can I use a CacheLoader for ?

A:

Some applications:

- HTTP sessions can be persisted (besides being replicated by JBossCache). The CacheLoader can be configured to be shared, or unshared, meaning that every node in a cluster has its own local store. It is also possible to attach a CacheLoader to just one of the nodes.

- Simple persistence for POJOs. Use of JBossCacheAop and a local CacheLoader persist POJOs transparently into the store provided by the CacheLoader.

- Highly available replicated and persisted data store. The service is up as long as at least 1 node is running, but even if all nodes are taken offline, when the first node is started again, the data previously saved will still be available (e.g. a shopping cart).

- A caching web proxy (a la Squid): all data are contents of URLs, users access the proxy, and if the URL is not in the cache, the CacheLoader fetches it from the web. This could actually be a replicated and transactional version of Squid.

Q: | How do I configure JBossCache with a CacheLoader ?
A: | Through XML: both the fully-qualified classname of the CacheLoader and its configuration string have to be given. JBossCache will then instantiate a CacheLoader. See JBossCache documentation for details.
Q: | Do I have to pay to use Sleepycat's CacheLoader ?
A: | Not if you use it only for personal use. As soon as you distribute your product with BdbjeCacheLoader, you have to purchase a commercial license from Sleepycat. See details at http://www.sleepycat.com/jeforjbosscache.