Open source Java projects: Java Caching System

A distributed caching system for enterprise applications

1 2 Page 2
Page 2 of 2
JCS cache = JCS.getInstance( "musicCache" );

You can put objects into the cache by invoking the JCS class's put() method, specifying a key and a value:

cache.put(new Integer(1), new Album(1, "Toby Mac", "Diverse City"));

You can then retrieve objects by invoking the JCS class's get() method, passing it the key of the object to retrieve:

Album album = ( Album )cache.get( id );

Finally, you can remove objects from the cache by invoking the JCS class's remove() method, passing it the key of the object to remove:

cache.remove( id );

The only requirement for objects to be stored in the cache is that they must be serializable, meaning that they must implement the java.io.Serializable interface and contain either primitive types, Strings, wrapper classes, or other serializable objects.

Listing 2 shows the code for the Album class, which is the cached object in this example.

Listing 2. The Album class

package com.geekcap.jcs;

public class Album implements java.io.Serializable
{
   private Integer id;
   private String artist;
   private String title;

   public Album() {
   }

   public Album( Integer id, String artist, String title ) {
     this.id = id;
     this.artist = artist;
     this.title = title;
   }

   public Integer getId() {
     return id;
   }

   public void setId( Integer id ) {
     this.id = id;
   }

   public String getArtist() {
     return artist;
   }

   public void setArtist( String artist ) {
     this.artist = artist;
   }

   public String getTitle() {
     return title;
   }

   public void setTitle( String title ) {
     this.title = title;
   }

   public String toString() {
     return artist + ": " + title;
   }
}

The Album class is just a thin, serializable, wrapper around three attributes: id, artist, and title. You can expand your objects to include additional fields and subobjects; you just need to ensure that they are serializable.

Listing 3 shows the contents of the MusicStore class, which demonstrates how to cache Albums.

Listing 3. The MusicStore class

package com.geekcap.jcs;

import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;

public class MusicStore
{
    private JCS cache;

    public MusicStore()
    {
        try
        {
            // Load the cache
            cache = JCS.getInstance( "musicCache" );

            // Initialize the cache
            cache.put( new Integer( 1 ),
                 new Album( 1, "Toby Mac", "Diverse City" ) );
            cache.put( new Integer( 2 ),
                 new Album( 2, "Pillar", "Fireproof" ) );
            cache.put( new Integer( 3 ),
                 new Album( 3, "Audio Adrenaline", "Underdog" ) );
        }
        catch( CacheException e )
        {
            e.printStackTrace();
        }
    }

    public void addAlbum( Album album )
    {
        try
        {
            cache.put( album.getId(), album );
        }
        catch( CacheException e )
        {
            e.printStackTrace();
        }
    }

    public Album getAlbum( Integer id )
    {
        return ( Album )cache.get( id );
    }

    public void removeAlbum( Integer id )
    {
        try
        {
            cache.remove( id );
        }
        catch( CacheException e )
        {
            e.printStackTrace();
        }
    }

    public static void main( String[] args )
    {
        MusicStore musicStore = new MusicStore();
        musicStore.addAlbum( new Album( 4, "The O.C. Supertones",
                                       "Supertones Strike Back" ) );
        Album album = musicStore.getAlbum( 1 );
        System.out.println( "Album 1: " + album );
        album = musicStore.getAlbum( 4 );
        System.out.println( "Album 4: " + album );
        musicStore.removeAlbum( 4 );
        album = musicStore.getAlbum( 4 );
        System.out.println( "Album 4: " + album );
    }
}

The MusicStore class retrieves the musicCache region from JCS in its constructor. Because the cache configuration file is named cache.ccf and is in the CLASSPATH, the getInstance() method causes JCS to load the cache properties and create the region. Subsequent getInstance() invocations would simply return the region that has already been created. The constructor then loads three albums into the cache by invoking the put() method.

The main() method demonstrates how to add an album, retrieve an album, and remove an album from the MusicStore, which simply delegates to one of the JCS cache methods.

Although this example runs as a standard Java class, a more realistic example would integrate these classes into an enterprise Java application. For example, the music store could be expanded to check for an object in the cache. If it doesn't find the object there, it would then query a database for the requested object, putting the result back into the cache. Then a servlet, a business object, or a Spring bean could use the music store as a service object.

In conclusion

The primary benefit of a cache is that objects can be served from local memory faster than they can be loaded from an external data source, such as a database located across a network. The drawback is that caches can consume a considerable amount of memory, and if objects and their usage patterns are not analyzed thoroughly, cache management can introduce another bottleneck into your application. If a cache appears to be a good fit once you analyze your objects, JCS is a great option.

Steven Haines is the founder and CEO of GeekCap, Inc., which provides technical e-learning solutions for software developers. Previously he was the Java EE Domain Expert at Quest Software, defining software used to monitor the performance of various Java EE application servers. He is the author of Pro Java EE 5 Performance Management and Optimization, Java 2 Primer Plus, and Java 2 From Scratch. He is the Java host on InformIT.com and a Java Community Editor on InfoQ.com. Steven has taught Java at the University of California, Irvine and Learning Tree University.

Learn more about this topic

More from JavaWorld

1 2 Page 2
Page 2 of 2