Caching in a JEE : don’t write it yourself, use LoadingCache from Google Guava libraries.

Caching data is something you use in almost every JEE project. Most of the time it’s pretty simple : put your data in a .properties file and use a PropertyManager to fetch the data.

But that’s not very flexible and manageable. Updating the values means, updating your property file, repackaging the ear file, and redeploying, and only developers can update the data.

Putting the data in JNDI entries, and using JNDI lookups may solve the problem of redeploying, but if you got a few 100 properties, it’s still not very manageable.

Most of the times, JNDI entries are entered via some application server console which, in a production environment, is not accessible for your users who need to manage this data.

So lets put the data that needs to be cached in a database, or make it accessible via a web service. That would be ideal. You can write your own application on it, and have the data managed by your users.

But that means that you have to write your own, thread safe, caching algorithms.

No big deal if the data only changes once every 10 years, but refreshing it on a time or size basis, makes the whole thing a bit more complicated. And that’s where the great LoadingCache class from the Google Guava library comes in.

What are the Guave libraries ? Well, here’s how they describe it : ‘The Guava project contains several of Google’s core libraries that we rely on in our Java-based projects: collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, and so forth.’

Now for caching, the Guava LoadingCache class caches data in a key-object map, and lets you define a cache refreshing mechanism, all done in a thread safe manner.

So lets show a small  example and explain how it works. Suppose your cache contains a list of products that are on sale for 1 day. Depending on the no. of sold products, the price will increase during that day. This means that the cache should be updated every few seconds, to update the price, and after 1 day, the whole cache should be refreshed with new products. Suppose that price setting and product selections are in the database, updated by some back-end application, and we need the new data in our frontend application and we want to cache it.

All this can be done with this simple class :

import java.util.concurrent.TimeUnit;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import be.iadvise.dao.DatabaseDAO;
import be.iadvise.entities.Product;
import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.MoreExecutors;

@Singleton
public class ProductCache {

@EJB
 DatabaseDAO databaseDAO;
 private static final Integer REFRESH_PRODUCT_AFTER_5_SECONDS = 5;
 private static final Integer EXPIRE_PRODUCT_AFTER_1_DAY = 1;
 private final LoadingCache<String, Optional<Product>> cache;

 public ProductCache() {
      cache = CacheBuilder.newBuilder()
           .expireAfterWrite(EXPIRE_PRODUCT_AFTER_1_DAY, TimeUnit.DAYS)
           .refreshAfterWrite(REFRESH_PRODUCT_AFTER_5_SECONDS, TimeUnit.SECONDS)
           .build( new CacheLoader<String, Optional<Product>>() {
                 @Override
                 public Optional<Product> load( String productId ) throws Exception {
                     return loadCache(productId);
                 }
           }
     );
 }

 public Optional<Product> getEntry( String productId ) {
      return cache.getUnchecked( productId );
 }

 private Optional<Product> loadCache(String productId) {
      Product product = databaseDAO.getProduct(productId);
      return Optional.fromNullable(product);
 }
}

Explanation

  1. In the constructor, we build the cache using the CacheLoader, defining the refresh mechanism. In our example we define 2 rules :
    – expireAfterWrite : after this period, the object will be evicted from the cache, and replaced the next time it is requested.
    – refreshAfterWrite : after this period, the object will be refreshed using the loadCache method. (with our new price)
  2. getEntry(String productId) method : will return the object with given key. So in this example, the cache is not loaded all at once, but only when the object is needed.
  3. loadCache(String productId) : will load the product and add it to the cache, or replace it if it’s already there and needs to be refreshed.

That’s all there is to it !

A few other remarks on the code

  1. There are other mechanism like expire/refresh AfterRead, which will time only from the last read, or let the cache hold only a certain no. of objects,…
  2. This code is implemented as a session bean. To make a singleton, I’m using EJB 3 annotation @Singleton. Because I only want 1 cache in my application
  3. My DAO is also injected using the @EJB annotation
  4. The LoadingCache does not want any null objects in the map (returns an error), so I’m using the Guava ‘Optional’ class here. This is basically a wrapper for my object and used to check if there is a value for my product id or not. So if someone uses a wrong productId, my cache will indicate that there is no product for this id, and I don’t have to go to the database every time it is requested.

To conclude:

Programming a caching mechanism in a JEE environment is not as trivial as it may seem. Testing it in a multithreaded environment is even more difficult. The caching classes of Guave gives you ready-to-use solution. It’s programmed, tested and used by Google, so I think we can say in all honesty : this is proven technology.

A remark on deploying on Weblogic 12c:

Weblogic also uses the Guava libraries, but an older version. This causes following error on deployment :

java.lang.NoSuchMethodError: com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor()

Lcom/google/common/util/concurrent/ListeningExecutorService;

Adding the following to your weblogic-application.xml will solve the problem (force weblogic to use your deployed Guava libraries :

<wls:prefer-application-packages>
<wls:package-name>
com.google.common.*
</wls:package-name>
<wls:prefer-application-packages>

Guava libraries run under Apache license, more info/download can be found on :

https://code.google.com/p/guava-libraries/

Have fun !

Oracle Open World 2010: Forms in the Middle of Middleware

People attending Open World to have a closer look at fusion technologies and how to integrate them in your existing applications, need to check out the following session:

  • ID#: S315945
  • Title: Oracle Forms in the Middle of Middleware with Oracle Product Management
  • Track: Application Servers, Application Grid, and Development
  • Date: 22-SEP-10 Time: 13:00 – 14:00
  • Venue: Marriott Marquis Room: Salon 9

Together with Grant Ronald we will talk you through the possible scenario’s to modernize your existing forms applications. After each scenario we will demo the functionalities and showcase some of the success stories we’ve conducted together with our benelux customers.

The different scenario’s include upgrading to 11g to use the event-driven architecture, integrate with existing applications such as apex, .net, google maps, bpel, …

In other words if you’re using fusion technologies such as BPEL, OSB, ADF, … you can easily integrate these with your existing forms applications using the new features provided in 11g.

Forms 11g javascript integration: Call others

Forms 11g holds a lot of interesting new features focused on event-driven architecture, one of these is javascript integration. There are two ways of using javascript with Forms 11g: “call others” and “let others call you”.

Javascript can call code in Forms(“Let others call you”) using the new forms trigger “when-custom-javacript-event”.

This post is going to show you the first one: “call others”, in other words call javascript from your Oracle Forms application.

During the Forms Modernization Seminar I showed a google map that could be manipulated from an Oracle Form. It’s an easy implementation with only a few lines of code(most of the javascript is taken from the api examples on the google code site: http://code.google.com/apis/maps/).

  • Build a little form with one (control) block, one text field(to enter an address) and one button(to call the javascript code).
  • Next step is to create an HTML-page to display the form.

This code puts the form(in an iframe) and the map side by side:
(Click to enlarge)

And it will look like this:

  • The javascript that will be called is put in another file google.js:

  • The only thing to do is creating a “when-button-pressed” trigger in forms to call the javascript function showAddress.
    This is done by a new built-in procedure web.javascript_eval_expr:
  • Copy the HTML and javascript file to the following directory:
    <middleware_home>\user_projects\domains\<domain>\servers\WLS_FORMS\tmp\_WL_user\formsapp_11.1.1\e18uoi\war\
  • Create a new configuration using Enterprise Manager:

  • Make sure the parameter EnableJavascriptEvent is set to “true’ in your configuration!

And the working demo…

Apex: integration of new Google API’s

Google has released 2 new features on it’s AJAX Search API:

  • Blog bar
  • News bar

Both bars allow you to incorporate dynamic content into the layout of your site.

I have tried to implement both features into ApEx and they were succesful. In this blog you can read a step by step guide explaining how to integrate the Blog Bar into your apex application.

The Blog Bar is offered in horizontal and vertical styles. You have the ability to let your users see specific Blog Search results or you can select only blogs specified by yourself.


The first thing you need to do is to register with Google.
Then you can go to Google Blog Bar API page and run the wizard to get the right example code and key. Save the example code and the key so you can use it later.

Now we can implement it into your ApEx page:

Paste your css and javascript code into the html header of your ApEx page but leave the next code out of it:

<div id=”blogBar-bar”>
<span style=”margin:10px;padding:4px;”>Loading…</span>
</div>

Now create an empty html region and paste the code you left out of your header into it:

Run your page:

The following example shows a horizontal style(only 1 line):

A working example can be found here.

The following example shows a vertical style:


A working example can be found here.

More info about customizing the google blog API can be found here.