An Article On Debugging EJB Without Deployment Using NetBeans IDE

Introduction
Developing EJB has never been easier. If there is any change in logic it has to be packaged and redeployed into container for debugging. Here I have discussed how EJB can be tested before deploying. This is one of the goals of EJB3.0. (refer EJB3.0 spec at http://java.sun.com/products/ejb/docs.html). Source code for discussed example is also attached.

Target Audience
This document is in particular a reading material for EJB Developers and any one who has the knowledge of Java,J2EE.

Tools Used
NetBeans3.6


Current Process


The process

  • All Java files are compiled
  • All class files are packaged into jar/ear
  • jar files are copied to server
  • server deploys the ejbs
  • Developer debugs the code. if code has to be changed steps from 1 to 4 have to be repeated.
  • Some J2ee server requires restarting for deployment.For each deployment restarting may be required.

New Process


The process

  • Required Java files are compiled
  • Developer debugs the code. if code has to be changed repeat steps from 1 to 2 have to be repeated.
  • J2ee container is not required for debugging.

I don’t need to explain advantages of this debugging style

Scenario

Let us assume we have to develop Employee Portal using EJB. Design contains an EmployeeServiceEJB and DepartmentServiceEJB. EmployeeServiceEJB gives name of the employee if employee id is passed. This EJB also returns department name of the employee if the id is passed. For that first it fetches department id from EmployeeServiceEJB which fetches department name from DepartmentServiceEJB.Let us see How it can be developed without deploying the EJBs into container.

Classes

Sequence


Hurdles for debugging in IDE

EmployeeServiceEJB_Skel (Name depends on the container) class will be generated while deploying into the container. It will be generated by the container.

So at the time of debugging this object is not available which makes it impossible to debug EJB without deploying.

Requirements

  • A framework which should enable ejb to be tested inside the Netbeans and the same objects should be deployed into container without any code change.
  • Junit test scripts should also test the code in IDE and container with out script change
  • While IDE is running server need not be started, which saves system RAM space and there by performance of the system.

Hurdles for debugging in IDE

  • Container generated classes are not available for debugging.
  • Connection pool is not available

Overcoming Container generated Problem using Business Interface & ServiceLocator

Container generated classes are for transaction, remoting, etc , In debugging point of view it is a delegation of call from Remote Interface to Bean class.

While debugging in IDE, work around is required to avoid calls for Skeleton Objects as they are not generated at the time of debugging

Business Interface

Using business interface bean method can be executed without calling container-generated classes. But however after deploying bean method should be called through these container-generated classes. This is achieved through Service locator.

Classes

Sequence while debugging

Code Snippet. [Check inheritance hierarchy in the class diagram]

EmployeeBusinessService getEmployeeBusinessService() {
	EmployeeBusinessService service = new EmployeeServiceEJB();
	return service;
}

Sequence after deployment

Code Snippet. [ Check inheritance hierarchy in the class diagram ]

EmployeeBusinessService getEmployeeBusinessService() {
     Context context = getContext("emp");        
     EmployeeServiceHome home = null;
     Object homeObject = context.lookup("emp/ejb/EmployeeServicess");
     home = (EmployeeServiceHome)PortableRemoteObject.narrow(homeObject,  EmployeeServiceHome.class);
                EmployeeService empService = home.create();
                return empService;
}

Service Locator

  • Two different paths are required while developing and deploying.
  • Incase of development BusinessInterface is assigned with BeanInstance.
  • If it is deployed in server BusinessInterface is assigned with RemoteInstance

ServiceLocator makes this decision based on the environment variable. This environment variable is configured on the server or IDE. A complete service locator method_

public EmployeeBusinessService getEmployeeService() throws BaseException {
        
        if( isServerDeployment() ){
            try {                
                Context context = getContext("emp");        
                EmployeeServiceHome home = null;
                Object homeObject = context.lookup("emp/ejb/EmployeeServices");
        home =EmployeeServiceHome)PortableRemoteObject.narrow(homeObject,  EmployeeServiceHome.class);
                EmployeeService empService = home.create();
  	//INSTANCE OF EMPLOYEE BEAN REMOTE INSTANCE
                return empService;
            }catch(Exception e) {
                e.printStackTrace();
                throw new BaseException(e.getMessage());
            }
        }else{
	//INSTANCE OF EMPLOYEE BEAN
            return new EmployeeServiceBean();
        }
    }


 protected boolean isServerDeployment() { 
String DEPLOYMENT_TYPE  = System.getProperty("deployment.type");         return ("Server".equalsIgnoreCase(DEPLOYMENT_TYPE))?true:false;
    }

  protected Context getContext(String appName) throws Exception  {
        Hashtable env = new Hashtable();  
        env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
        env.put(Context.SECURITY_PRINCIPAL, SECURITY_PRINCIPAL);
        env.put(Context.SECURITY_CREDENTIALS, SECURITY_CREDENTIALS);
        env.put(Context.PROVIDER_URL, BASE_PROVIDER_URL+appName);
        System.out.println("Connecting to Base URL"+ BASE_PROVIDER_URL+appName);
        return  new InitialContext(env);
    }

Environment variable deployment.type can be set using -d option. In server start up script -ddeployment.type=server In ide java parameter -ddeployment.type=ide


Connection pool Availability

Since connection pool is not available in IDE environment a direct connection is required at the time of debugging.

If code is executed in server jvm it will pickup pooled connection else a direct connection is created.

protected Connection getConnection() throws  SQLException {
        
        Connection con = null;
        
        try {
            if( isServerDeployment() ) {
                con = getPooledConnection();
            }else {
                con = getDirectConnection();
            }
            
        }catch(SQLException sqle) {
            throw sqle;
 }catch (Exception e){
            e.printStackTrace();
        }
        return con;
    }

Unit Testing

An EJB can be unit tested using JUNIT test scripts

public void testGetEmpName() throws Exception {
        EmployeeBusinessService business = EmployeeServiceLocator.getInstance().getEmployeeService();
        String name= business.getEmpName("1234");
        assertEquals(name,"abcd");
    }

if this test script is run using deployment.type=ide it will be executed inside the IDE else it will call the method in the container.ie the same script can be used to test while developing and after deployment.For this jndi.properties should be set properly

Log4j

if log4j is used for logging, it has to be initialized with log4j.properties.The following code snippet does it

org.apache.log4j.PropertyConfigurator.configure("{server.dir}/log4j.properties");

Screen shots


Setting environment variable

Debugging in IDE

Debugging ejb deployed in container

This is achieved by changing deployment.type=server

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo