Using a Singleton for ORB.init()
iPlanetTM Application Server Samples

Updated June 11, 2001

When you develop a web application or EJB that leverages a backend CORBA object, you have several options as to how your client code within the application server initializes the ORB. If you simply call ORB.init() from within a servlet's init() method or from within an EJB's ejbCreate() method, an ORB instance will be instantiated for every instance of the servlet and EJB class. For small scale implementations, this basic approach may be all that you need to support the expected load on your system. However, for large scale implementations, you should consider implementing the singleton design pattern to minimize the number of ORB instances within the application server.

For an introduction to using singletons, refer to the article "When is a Singleton Not a Singleton?" written by Joshua Fox of JavaWorld:

http://developer.java.sun.com/developer/technicalArticles/Programming/singletons/

To arrive at the best solution for your environment, it is recommended that you exercise several solutions within a production-like environment. As you run performance tests, monitor JVM memory consumption, file descriptor usage and response times to determine the relative behavior of each approach.

Singleton Implementation in the Samples

The backend CORBA samples provided with iPlanet Application utilize a very simple singleton OrbSingleton to carry out ORB initialization. You can find the source code for OrbSingleton in the directory:

install_dir/ias6/ias/ias-samples/corba/backend/orbix/common/src/

The servlet init() and ejbCreate() methods call getInstance() on the singleton to obtain a reference to the singleton. Then getOrb() is called to obtain a reference to the initialized ORB:

public class CorbaClientServlet extends HttpServlet {

    ...

    public void init (ServletConfig config) throws ServletException

    {

      ...

      OrbSingleton orbSingleton = OrbSingleton.getInstance (orbDomainName, orbCfgDir);

      orb = orbSingleton.getOrb();

      ...



public class CorbaClientEJB implements javax.ejb.SessionBean {

    ...

    public void ejbCreate() throws java.rmi.RemoteException, javax.ejb.CreateException

    {

      ...

      OrbSingleton orbSingleton = OrbSingleton.getInstance (orbDomainName, orbCfgDir);

      orb = orbSingleton.getOrb();

      ...

When getInstance() is called, the singleton class simply checks to determine whether or not the ORB has already been initialized:

public class OrbSingleton {

  private ORB orb;

  static private String orbDomain = null;

  static private String orbCfg = null;

  static private OrbSingleton _instance = null;

  ...

  static public synchronized OrbSingleton getInstance(String orbDomainName, String orbCfgDir)

  {

    if (null == _instance) {

      orbDomain = orbDomainName;

      orbCfg = orbCfgDir;

      _instance = new OrbSingleton();

    }

    return _instance;

  }

  ...

If the instance has not already been created, then the constructor for the class is called to create a new instance:


  public class OrbSingleton {

    private ORB orb;

    static private String orbDomain = null;

    static private String orbCfg = null;

 	static private OrbSingleton _instance = null;

    ...

    private OrbSingleton() {

      ...

      try {

        orb = ORB.init(args, orbProperties);

      }

      catch (SystemException ex) {

        System.out.println("OrbSingleton() constructor: ORB.init() exception: " + SystemExceptionDisplayHelper.toString(ex));

      }

    }

  ...

The getOrb() method simply returns the ORB instance reference:

    public class OrbSingleton {

      private ORB orb;

      static private String orbDomain = null;

      static private String orbCfg = null;

      static private OrbSingleton _instance = null;

      ...

      public ORB getOrb()

      {

        return orb;

      }

    ...

When running the servlet client to the backend EJB to CORBA sample for Orbix, you'll see the following output in the Java engine (kjs) log file as you run the sample for the first time. Since the singleton does not yet exist, you see the constructor of the OrbSingleton class being called. The ORB.init() is called within the constructor:

Looking up: java:comp/env/ejb/CorbaClient

Creating the CorbaClient bean

Calling CorbaClient bean to do some work.

CorbaClientEJB: ejbCreate() started on obj samples.corba.backend.orbix.ejb.bean.

CorbaClientEJB@7ebe1

CorbaClientEJB: Initializing ORB

CorbaClientEJB: orbDomainName=localhost

CorbaClientEJB: orbCfgDir=c:\progra~1\iona\orbix_art\1.2\localhost

CorbaClientEJB: iorFile1=c:\\program files\\iona\\orbix_art\\1.2\\simple1.ior

CorbaClientEJB: iorFile1=c:\\program files\\iona\\orbix_art\\1.2\\simple1.ior

ejbCreate() started on obj samples.corba.backend.orbix.common.OrbSingleton@f11b8

OrbSingleton() constructor: Calling ORB.init().

OrbSingleton() constructor: orbDomainName=localhost

OrbSingleton() constructor: orbCfgDir=c:\progra~1\iona\orbix_art\1.2\localhost

OrbSingleton() constructor: ORB.init() successful.

CorbaClientEJB: Invoking import_object() for first object

CorbaClientEJB: Reading object reference from c:\\program files\\iona\\orbix_art

\\1.2\\simple1.ior

CorbaClientEJB: Invoking import_object() for second object

CorbaClientEJB: Reading object reference from c:\\program files\\iona\\orbix_art

\\1.2\\simple2.ior

CorbaClientEJB: Invoking narrow on first object.

CorbaClientEJB: Invoking narrow on second object.

If you start several browsers and repeatedly hit reload to send multiple concurrent requests to the application server, the EJB container will create additional instances of the stateless session bean. During creation of each additional stateless session bean instance, the ejbCreate() method will be called. By reviewing the Java engine log files, you can see that the OrbSingleton().getInstance() method prints out a message stating that a singleton already exists. In this case the original ORB reference is returned to the new EJB instance:


Looking up: java:comp/env/ejb/CorbaClient

Creating the CorbaClient bean

Calling CorbaClient bean to do some work.

CorbaClientEJB: ejbCreate() started on obj samples.corba.backend.orbix.ejb.bean.

CorbaClientEJB@7db00d

CorbaClientEJB: Initializing ORB

CorbaClientEJB: orbDomainName=localhost

CorbaClientEJB: orbCfgDir=c:\progra~1\iona\orbix_art\1.2\localhost

CorbaClientEJB: iorFile1=c:\\program files\\iona\\orbix_art\\1.2\\simple1.ior

CorbaClientEJB: iorFile1=c:\\program files\\iona\\orbix_art\\1.2\\simple1.ior

OrbSingleton().getInstance(): Singleton already exists.

CorbaClientEJB: Invoking import_object() for first object

CorbaClientEJB: Reading object reference from c:\\program files\\iona\\orbix_art

\\1.2\\simple1.ior

CorbaClientEJB: Invoking import_object() for second object

CorbaClientEJB: Reading object reference from c:\\program files\\iona\\orbix_art

\\1.2\\simple2.ior

CorbaClientEJB: Invoking narrow on first object.

CorbaClientEJB: Invoking narrow on second object.



CorbaClientEJB: ejbCreate() finished on obj samples.corba.backend.orbix.ejb.bean

.CorbaClientEJB@7db00d 

Although this simple approach to implementing the singleton design pattern will help minimize the number of ORB instances created within a JVM of the application server, it will not always result in a single instance being created throughout a JVM. The manner in which an application server manages class loading has a significant impact on the number of singletons created within each JVM.

Class Loading Impact on Singletons

iPlanet Application Server implements a hierarchy of class loaders to manage system classes, J2EE applications and individual J2EE modules. Since a singleton cannot span multiple class loaders, it is important to understand the basics of class loading in the application server when considering singletons.

J2EE Application Deployments

If you deploy a J2EE application as an EAR file, within each Java engine (JVM), the application server dedicates a class loader to the application. All classes deployed as part of the WAR and EJB JAR files within the EAR are loaded by the same class loader. If you implement a singleton anywhere within the EAR, you are able to ensure that at most one instance of the singleton will be created for that application within a JVM process.

However, if multiple applications contain the same singleton class, you will see multiple instances of the singleton created because separate class loaders are used for each application. This behavior may or may not be acceptable in your environment. If you exercise both the servlet and EJB backend CORBA sample applications, you will notice that the common singleton class shared by these two applications is created twice.

To avoid instantiating multiple copies of the same singleton class, you can deploy your application code as individual modules.

Module-based Deployments

Since the application server uses a common class loader for all applications deployed as individual WAR and EJB JAR modules, you can deploy your applications as individual modules and be assured that a common class loader would create only one instance of a singleton throughout a JVM process. You must weigh the costs and benefits of deploying your applications as individual modules to achieve a true singleton support within a JVM as compared to perhaps having a small number of J2EE applications each creating their own copy of the singleton.

Application Server Classpath

Although it involves more deployment of your application classes, you could add the singleton class to the application server's classpath and not include it in the J2EE modules or application. This approach would force the creation of at most one instance of the singleton class for the entire application server instance.

Copyright (c) 2001 Sun Microsystems, Inc. All rights reserved.