An Article On Debugging EJB Without Deployment Using NetBeans IDEContributed by Raguraman Krishnamurthy as part of the Win With NetBeans comptetition
Introduction
Target Audience
Tools Used Current Process
The process
New Process
The process
I don’t need to explain advantages of this debugging style ScenarioLet 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 IDEEmployeeServiceEJB_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
Hurdles for debugging in IDE
Overcoming Container generated Problem using Business Interface & ServiceLocatorContainer 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 InterfaceUsing 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 deploymentCode 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
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 AvailabilitySince 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 TestingAn 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 Log4jif 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 shotsSetting environment variable
Debugging in IDE
Debugging ejb deployed in containerThis is achieved by changing deployment.type=server
|