Create an object factory to return a Singleton Java Object Instance

Purpose  of this tutorial

  • Create and deploy your custom Wildfly module
  • Create an Object Factory class which instantiates a Singleton Instance of our TestBean class
  • Build a Test client [ pure java SE program ] using remote JNDI to lookup our Remote Object Factory MyObjectFactory

Requirements

  • Set classpath :  $ export CLASSPATH=/usr/local/wildfly-8.2.0.Final/bin/client/jboss-client.jar:.
  • Tested with   Wildfly 8.0.2

JAVA Code [ Server Side ]

 
MyObjectFactory.java:

package hhu.object_factory;
/**
 * @author Helmut Hutzler
 */
import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;import javax.naming.spi.ObjectFactory;
import hhu.object_factory.TestBean;
public class MyObjectFactory implements ObjectFactory
 {
    /*
       Note we need to restart the Wilfdly server when we change the  MyObjectFactory object !
       Making constructor  MyObjectFactory() as private to prevent access to outsiders
       The instance of  TestBean()  is created at the startup of the class and remains valid
         until someone shutdown the  JVM.
       Since TestBean is a static, it gets loaded and created during loading of the MyObjectFactory class.
       Calling getObjectInstance does not instantiate the TestBean class a 2.nd time
    */
    private static volatile TestBean bean =  new TestBean("City","Sattelmannsburg - ( believe me - this is not  in India)");
    
       public MyObjectFactory()
       {
            System.out.println(" NEW: [MyCustomObjectFactory] MyCustomObjectFactory initialized.");
       }

       public Object getObjectInstance(Object obj, Name name, Context nameCtx,Hashtable environment) throws Exception
       {
            // TestBean bean = new TestBean("City","Pune (India)");
            return bean;
       }
   }

TestBean.java:
package hhu.object_factory;
/**
 *
 * @author Helmut Hutzler 
 */
public class TestBean implements java.io.Serializable
  {
      private String name;
      private String value;
      private long itime;

    public long getItime()
      {
        return itime;
      }
      
      public TestBean(String name,String value)
       {
         this.name=name;
         this.value=value;
         this.itime=System.currentTimeMillis();
         System.out.println("[TestBean] TestBean initialized - itime: " + this.itime);
       }

      public String getName()
       {
          return name;
       }
      public String getValue()
       {
          return value;
       }
      
  }

Deploy our JAR file as a Wildfly Module

Assemble jar file WF_Object_Factory.jar  with following files 

[oracle@wls1 dist]$ pwd 
/home/oracle/NetBeansProjects/GIT/WF_Object_Factory/dist
[oracle@wls1 dist]$  jar tvf WF_Object_Factory.jar
     0 Fri Mar 13 17:50:52 CET 2015 META-INF/
   177 Fri Mar 13 17:50:50 CET 2015 META-INF/MANIFEST.MF
     0 Fri Mar 13 17:50:50 CET 2015 hhu/
     0 Fri Mar 13 17:50:50 CET 2015 hhu/object_factory/
  1135 Fri Mar 13 17:50:50 CET 2015 hhu/object_factory/MyObjectFactory.class
   818 Fri Mar 13 17:50:50 CET 2015 hhu/object_factory/TestBean.class

Deploy JAR file 
[oracle@wls1 dist]$ cd /home/oracle/NetBeansProjects/GIT/WF_Object_Factory/dist
[oracle@wls1 dist]$ mkdir -p $WILDFLY_HOME/modules/object_factory/main
[oracle@wls1 dist]$ cp /home/oracle/NetBeansProjects/GIT/WF_Object_Factory/dist/WF_Object_Factory.jar  
                       $WILDFLY_HOME/modules/object_factory/main 
[oracle@wls1 dist]$ cd    $WILDFLY_HOME/modules/object_factory/main 
[oracle@wls1 dist]$ pwd 
/usr/local/wildfly-8.2.0.Final/modules/object_factory_wf/main
[oracle@wls1 main]$ ls -l
total 8
-rw-rw-r-- 1 oracle oracle  265 Mar 12 16:03 module.xml
-rw-rw-r-- 1 oracle oracle 2819 Mar 12 15:52 Object_Factory_WF.jar

Create a module.xml with following content
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.4" name="object_factory">
   <resources>
       <resource-root path="WF_Object_Factory.jar"/>
   </resources>
  <dependencies>
       <module name="javax.api"/>
  </dependencies>
</module>
Verify module.xml entries
[oracle@wls1 main]$ ls ../../object_factory
main
[oracle@wls1 main]$ ls WF_Object_Factory.jar
WF_Object_Factory.jar

Module Management - Load the module a first time 

[oracle@wls1 JNDI]$   $WILDFLY_HOME/bin/jboss-cli.sh --connect --file=obj_factory_jndi.cli
obj_factory_jndi.cli : 
/subsystem=naming/binding=java\:jboss\/exported\/object_factory/:add(binding-type=object-factory,module=object_factory,class=hhu.object_factory.MyObjectFactory

Server log should report: 
17:41:13,286 INFO  [stdout] (management-handler-thread - 4) [TestBean] TestBean initialized - itime: 1426351273285
17:41:13,286 INFO  [stdout] (management-handler-thread - 4)  NEW: [MyCustomObjectFactory] MyCustomObjectFactory initialized.
2015-03-14 17:41:13,286 INFO  [stdout] (management-handler-thread - 4) [TestBean] TestBean initialized - itime: 1426351273285
2015-03-14 17:41:13,286 INFO  [stdout] (management-handler-thread - 4)  NEW: [MyCustomObjectFactory] MyCustomObjectFactory initialized.

Note if you need to change the MyObjectFactory.class or TestBean.class you need to restart your Wildfly server 

In case you need to remove the module run :
[oracle@wls1 JNDI]$ cat rm_obj_factory_jndi.cli
/subsystem=naming/binding=java\:jboss\/exported\/object_factory/:remove

[oracle@wls1 JNDI]$   $WILDFLY_HOME/bin/jboss-cli.sh --connect --file=rm_obj_factory_jndi.cli
{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}
--> restart Wildfly

Build and run Remote JNDI test program

BindJndiDemo.java:

import java.io.*;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class BindJndiDemo
{
public final static String JNDI_FACTORY="org.jboss.naming.remote.client.InitialContextFactory";

public static void main(String[] args) throws Exception
  {
     if (args.length != 1) {
         System.out.println("Usage: java BindJndiDemo URL");
         System.out.println("Example:  java BindJndiDemo  http-remoting://127.0.0.1:8180");
         return;
     } 

     InitialContext ic = getInitialContext(args[0]);
     BindJndiDemo demo = new BindJndiDemo();
     String jnid_lookup = "java:object_factory";
     hhu.object_factory.TestBean testBean=(hhu.object_factory.TestBean)ic.lookup(jnid_lookup);
     System.out.println("\t(hhu.object_factory.TestBean)ic.lookup(jnid_lookup) testBean = "+testBean);
     System.out.println("\tname="+testBean.getName()+"\tvalue="+testBean.getValue()+" - Object Inst. Time: " + testBean.getItime());
     System.out.println("");
  }

private static InitialContext getInitialContext(String url) throws NamingException
     {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
        env.put(Context.PROVIDER_URL, url);

        env.put(Context.SECURITY_PRINCIPAL, "oracle");
        env.put(Context.SECURITY_CREDENTIALS, "helmut11");
        InitialContext ic=new InitialContext(env);
        System.out.println("\t Got InitialContext ic: "+ic);
         return ic;
      }
}

Test Client: 
[oracle@wls1 JNDI]$  java BindJndiDemo  http-remoting://127.0.0.1:8180
Mar 14, 2015 5:47:17 PM org.xnio.Xnio <clinit>
INFO: XNIO version 3.3.0.Final
Mar 14, 2015 5:47:17 PM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.3.0.Final
Mar 14, 2015 5:47:17 PM org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 4.0.6.Final
     Got InitialContext ic: javax.naming.InitialContext@5cef8a56
    (hhu.object_factory.TestBean)ic.lookup(jnid_lookup) testBean = hhu.object_factory.TestBean@7c91f442
    name=City    value=Sattelmannsburg - ( believe me - this is not  in India) - Object Inst. Time: 1426351273285

Rerunning Test client: 
[oracle@wls1 JNDI]$  java BindJndiDemo  http-remoting://127.0.0.1:8180
Mar 14, 2015 5:47:19 PM org.xnio.Xnio <clinit>
...
    (hhu.object_factory.TestBean)ic.lookup(jnid_lookup) testBean = hhu.object_factory.TestBean@7c91f442
    name=City    value=Sattelmannsburg - ( believe me - this is not  in India) - Object Inst. Time: 1426351273285

--> The Object Instantiation time is always 1426351273285 so we can sure it is the same object!

Reference

Leave a Reply

Your email address will not be published. Required fields are marked *