SERVICE LOCATOR - AN IMPLEMENTATION
by Rahul Mahindrakar

Patterns have become very important and indespensible for Architects and Programmers. This is because provide reusable solutions to recurring problems in different contexts and also provide a language to describe them. The important point here is reuability of the same solution again and again .

J2EE provides its own set of patterns, other than the core design patterns. I have been working on the J2EE patterns for the past few weeks. The ServiceLocator pattern interests me a lot. This pattern tries to encapsulate complex interfaces and network operations to service lookup and creation. The basic aim of this article is to provide an implementation to this pattern. The aim is to be able to reuse this same class over different projects in J2EE without code change.

All J2EE clients that want to access components like EJB’s, JMS Queues and DataSource need to access them through a lookup. A typical lookup involves the following

 InitialContext ic= new InitialContext();
  ABCHome	home=(ABCHome) ic.lookup(“ABCHome” ;) ;
For EJB lookup’s addition actions like PortableRemoteObject.narrow() need to be invoked.

The above lines of code recur again and again in the web layer that accesses the Business layer. This type of code may also recur in the Business layer as one EJB access another like in the Business Fašade pattern. This can cause the following problems

The servicelocator pattern tries to solve the above problem. Using this you will have to replace the above code with
ABCHome home = 
    (ABCHome) ServiceLocator.getInstance().getHome(“ABCHome”, ABCHome.class , true) ;
Types of Clients of ServiceLocator
  1. Java Clients
  2. Web tier based clients like jsp, servlets , utility classes
  3. EJB tier clients
Normally for Web based clients and EJB tier clients the ServiceLocator.getInstance() should work in all application servers. However with Java Clients certain properties need to be set up before the getInstance() is called. These properties can be passed via the setup(Properties p) method call. Note that this method must be called the before the getInstance is called the first time.

Servlce Lookup Strategies

There following strategies can be followed in the ServiceLocator Pattern.

1. The lookup Names exist in the Web layer or Business layer. In this scenario the JNDI name to be looked up are passed from this layer. The problem here is that multiple objects looking up the same object may hardcode the lookup names in code like in the line 1 above. This is the same problem that we talked of earlier. To solve this problem one can look up the JNDI names and other properties through a property file. This is very easy to implement and solves the problem.

2. A second solution introduces the concept of services and in this case we move the lookup specific variables into a Services class. A service encapsulates the users from the complexities like JNDI names, Home class names , remote class names etc. The requestor of the services knows just the service which is defined in the Services class. This is something like

Services.CustomerService
This is passed to the ServiceLocator class. The service locater API then determines based on the service what all parameters it requires and get this from the services class. The Service specific parameters can be in the ServiceLocator class,or in an inner class or in a different class. We here have implemented this in a totally new class with package access. This is to prevent others from modifying the main ServiceLocator class. Package access has been provided to the methods of the Services class so that the ServiceLocator class can access them. Other classes can only access the public defined services of Services class. The properties can also be got from a properties file.

In both the cases the properties file strategy is recommended so that changes to code need not be done in case of change in properties.

In this case the ServiceLocator can be invoked as follows

ABCHome home = (ABCHome) 
      ServiceLocator.getInstance().getHome(ServiceLocator. CustomerService, true);
Cached / UnCached Lookups

There are also two types of Service lookups through the ServiceLocater. These two types are Cached and UnCached lookups.

The Cached lookups can be made through passing the a Boolean of true to all lookup methods for the pFromCache parameter

The Uncached lookups can be made through passing a Boolean of false to all lookup method for the pFromCache parameter.

Another difference between Cached and Uncached lookups is that the Uncached lookups do not create the Cache. Thus the first time a Cached lookup Is made a JNDI lookup will take place even though a Uncached lookup has been made earlier for the same service.

Lets talk “implementation”

The implementation thus

1) Undertakes JNDI Lookups for various objects like

2) Undertakes cacheing of the above objects
3) Provides an uncached version to those who do not wish to implement cacheing
4) Provides strategies wherein the jndi names, EjbHomes, EjbObject class names may not be coded in the client but rather in the Services
5) Provides access to the EJBRemoteObject directly without accessing the EjbHome (see method getStatelessEJB().
6) The Cache is not created with a lookup of false passed in the parameter

Resources:
Core J2EE Patterns

There is a Java class too and here is the code