Friday, September 11, 2009

Spring JNDI Bind Utility for Unit Tests


Spring does provide JndiTemplate class for JNDI lookup through spring configuration. But there is not such convenience class for binding Objects to jndi server through configuration.
Through there are some classes like SimpleNamingContextBuilder that can be used programmatically but not via configuration (at least as it is).

Here I am presenting a utility class that be used to register jndi objects via Spring configuration.
For demo purpose commons-dbcp classes are used as resources to be bound to the jndi server.

The JNDI server used is file based RefFSContextFactory from sun. Any other JNDI Server would also suffice

Prerequisites
spring-core-2.5.6.jar
spring-beans-2.5.6.jar
spring-context-2.5.6.jar
providerutil.jar (referenced from fscontext)
The following jars are required for the demo sample only

I am presenting two version of the JNDI Binder utility class; one extends JndiTemplate and the other one extends InitialContext.


Binder Utility based on Spring's JndiTemplate class: JndiBinderTemplate
package in.spring.jndi.util;

import java.util.Iterator;
import java.util.Map;
import javax.naming.NamingException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jndi.JndiTemplate;

/**
* A Spring specific utility class to register objects to a jndi server through spring configuration
* Sample usage with file based jndi server
*
* Instead of using interfaces InitializingBean and DisposableBean, @PostConstruct and @PreDestroy
* annotations or init-method can be used
* @see org.springframework.jndi.JndiTemplate
* @author Vijesh
*
*/
public class JndiBinderTemplate extends JndiTemplate implements InitializingBean, DisposableBean  {

private Map jndiObjects;

public Map getJndiObjects() {
return jndiObjects;
}

public void setJndiObjects(Map jndiObjects) {
this.jndiObjects = jndiObjects;
// if life cycle interfaces are not available
// call loadJndi(); here
}

@Override
public void afterPropertiesSet() throws Exception {
loadJndi(); 
}


public void loadJndi() {
System.out.println(" start binding Objects to JNDI server ");

if(jndiObjects != null && !jndiObjects.isEmpty()) {

Iterator itr = jndiObjects.entrySet().iterator();

while (itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();

try {
rebind((String) entry.getKey(),entry.getValue());
} catch (NamingException e) {
System.out.println(" Binding "+entry.getKey()+" is failed with error: "+e.getMessage());
}  
}

System.out.println(jndiObjects.size()+" Objects bound to JNDI server ..");
}
}


@Override
public void destroy()  throws Exception {
clearJndi();
}


public void clearJndi() {
System.out.println(" unbind the Objects from the JNDI server  ");

if(jndiObjects != null && !jndiObjects.isEmpty()) {
Iterator itr = jndiObjects.keySet().iterator();

while (itr.hasNext()) {
String jndi = null;
try {
jndi = (String) itr.next();
unbind(jndi);
} catch (NamingException e) {
System.out.println(" Error in unbinding "+jndi);
e.printStackTrace();
}
}
}
}
}

The Spring configuration for the above class with some sample resources used to bind to the JNDI server is:



 


com.sun.jndi.fscontext.RefFSContextFactory
file:/




















Now the look up from the jndi consumer classes using will happen as expected. For example the following code would work perfectly fine.

/**
* Jndi lookup using Standard mechanism
*/
public void testJNDIBinder() {

System.out.println("\n in testJNDIBinder ");

System.setProperty("java.naming.factory.initial", "com.sun.jndi.fscontext.RefFSContextFactory");
System.setProperty("java.naming.provider.url", "file:/");

try {
Context cxt = new InitialContext();

Object obj1 = cxt.lookup("jndi/sDS");
System.out.println(" obj1 "+obj1);
Object obj2 = cxt.lookup("jndi/pDS");
System.out.println(" obj2 "+obj2);

System.out.println(" Look up test is successful.... ");

} catch (NamingException e) {
System.out.println(" Look up test failed.... ");
e.printStackTrace();
}
}


Binder Utility without Spring dependency: JndiBinderContext

The second class is very much similar to the one shown above except for it extends the class InitialContext

package in.spring.jndi.util;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
* A standard utility class to register objects to a jndi server through spring configuration
* Sample usage with file based jndi server
* @see javax.naming.InitialContext
* @author Vijesh
*/
public class JndiBinderContext extends InitialContext {

public JndiBinderContext() throws NamingException {
super(); 
}

public JndiBinderContext(Hashtable env) throws NamingException {
super(env);
}

// Rest is almost same as JndiBinderTemplate class, refer the source code for details



Another main difference is in passing the environment properties. In this case they are passed as constructor arguments (it is so in InitialContext)


    




com.sun.jndi.fscontext.RefFSContextFactory
file:/


















Please note that both the classes should be loaded lazily.

It's really unfortunate that Spring didn't provide a similar utility class. Why didn't it occurred to them when they created JndiTemplate class for lookup purpose?

Download the source (eclipse project)
The dependent libraries listed in the prerequisites should be downloaded separately and added to the project.

Even though I have used particular version of each dependent libraries, it doesn't mean that the utility will work only with that. As you can see, it is a simple class and should work with the earlier releases of the dependent libraries.

Friday, February 20, 2009

JavaFX CRUD Application

Well, I too jumped into the JavaFX bandwagon. Since I have good exposure to Swing, naturally I got excited by the new Rich Client Platform offering from Sun.

Most of of the examples using JavaFX available in Internet are demonstrating the graphic and animation capabilities of JavaFX and very few concentrates on Enterprise application needs. Yes I understand that one of the objective of JavaFX is to compete with other RIA/RCP offerings and the enterprise data centric application needs are already taken care of by Java Swing and web technologies.

Since my experience is mainly in developing data centric applications in enterprise world, I thought of creating a sample CRUD application that would use components from both JavaFX and Swing, former being the runtime and having major presence.

http://www.learntechnology.net/ has nice set of sample applications using most of the commonly used technology/frameworks and all of them are based on the same data model (Employee-Department). I liked the idea behind this site and decided to develop my JavaFX example using the same model, infact it uses the data layer from one of the samples there and make contribution.



Please find the lesson and source at http://www.learntechnology.net/content/javafx/javafx.jsp

Click the button to start the above example using Java Webstart:

Thursday, February 5, 2009

JBoss4 Admin Reference Card

I have been working with JBoss quiet often recently. Though lot of documentations and tutorials are availble, they are scattered. Besides there is no reference card available for JBoss as of now. So thought of authering one.

This reference card or cheatsheet is an attempt to provide a concise view of most commonly used tasks from a JBoss production environment administrators view.

Please find the reference card at the following location.


Your feedbacks are welcome to improve the RefCard

Thursday, January 8, 2009

Running JBoss as a Windows Service


What you need to know to run a JBoss server instance as a Windows Service.

Until recently it was done by using JavaService.exe or tanuki wrapper. Both involved quite a bit of configurations compared to what's available directly from JBoss.

Please note that this features is available in JBoss 5 by default. No need to download the files from jboss-native.

This solution will work with JBoss 4 too. I have tested it on JBoss 4.0.3, JBoss 4.2.3 and JBoss 5.0.0.

Some information is available at http://jboss.org/community/docs/DOC-10679


You will find links for different windows versions, select the appropriate one.

The downloaded file will be in .zip format, unzip it somewhere.

Copy jbosssvc.exe, service.bat and README-service.txt to your JBOSS_HOME/bin folder.

The file README-service.txt contains instructions on configurations changes.

Unfortunately the above file doesn't explain the part about service name related configuration

By default the service.bat contains settings entered for JBoss 5.

set SVCNAME=JBAS50SVC
set SVCDISP=JBoss Application Server 5.0
set SVCDESC=JBoss Application Server 5.0.0 GA/Platform: Windows x86

You may want to change it you describe your environment. If you are running multiple JBoss instances in machine, make sure you are using different values for SVNNAME in each instance.

Let's say you are using it with JBoss 4.0.3:

set SVCNAME=JBAS403SVC
set SVCDISP=JBoss Application Server 4.0.3
set SVCDESC=JBoss Application Server 4.0.3 GA/Platform: Windows x86

Next part to look at is where run.bat and shutdown.bat is referred. You may want to modify there if you want to pass arguments these batch files.

e.g.

jbosssvc.exe -p 1 "Starting %SVCDISP%" > run.log
call run.bat -c all -b 127.0.0.1 < .r.lock >> run.log 2>&1
jbosssvc.exe -p 1 "Shutdown %SVCDISP% service" >> run.log

run.log file is where console output is written to. 

jbosssvc.exe -p 1 "Shutting down %SVCDISP%" > shutdown.log
call shutdown -S --server=myserver:2099 < .s.lock >> shutdown.log 2>&1
jbosssvc.exe -p 1 "Shutdown %SVCDISP% service" >> shutdown.log

shutdown.log contains console outputs after service is stopped

To create/register the JBoss service with the windows service manager (This needs to be done only once)

JBOSS_HOME/bin> service.bat install.

Now the service will be available in the windows services manager. It can be modified and operated just like any other service.

If you ever want to remove the JBoss service from Windows, use the following command:

JBOSS_HOME/bin> service.bat uninstall.

That's all....

BTW, why JBoss is run as a Windows Service?
  • Automatically starts the process on system startup, and closes it on shutdown (when automatic) 
  • It launches the application as Windows service at system boot, before user logon and runs it without the need of a user session. 
  • Standard windows service monitoring mechanism can be utilized to check the application availability 
  • The application can be started using 'service account' without having to login as that user.