Table of Contents
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!