Getting an EJB session bean which uses @SecurityDomain annotation, in a unit test case through JNDI
nitin.bhardwaj21 May 13, 2010 7:31 AMHi Friends,
I am a novice in setting up unit testing framework. I am trying it for a Struts+EJB3 application. I intend to write a test case for each method that I write in a EJB3 session bean.
I am using JBoss AS 4.2.2, JDK1.5, and EJB3.1 for this application. The authentication is JAAS based and defined as follows in the login-config.xml:
<application-policy name = "emLoginPolicy">
<authentication>
<login-module code = "org.jboss.security.auth.spi.UsersRolesLoginModule"
flag = "required">
<module-option name = "unauthenticatedIdentity">guest</module-option>
<module-option name="usersProperties">users.properties</module-option>
<module-option name="rolesProperties">roles.properties</module-option>
</login-module>
</authentication>
</application-policy>
I wrote the following simple test class:
package com.nit.ejb.session.employee;
import java.util.Enumeration;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import com.nit.ejb.entity.Employee;
import com.nit.ejb.session.employee.remote.EmployeeServiceRemote;
import junit.framework.TestCase;
public class EmployeeServiceTest2 extends TestCase {
private EmployeeServiceRemote employeeService=null;
private String server="localhost:1099";
private String principal="E001";
private String credentials="Avi";
public EmployeeServiceTest2(String name) {
super(name);
}
protected void setUp() throws Exception {
super.setUp();
Properties props = new Properties();
//props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.auth.spi.UsersRolesLoginModule");
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
props.put(Context.SECURITY_AUTHENTICATION, "simple");
props.put(Context.SECURITY_PRINCIPAL, principal);
props.put(Context.SECURITY_CREDENTIALS, credentials);
props.put(Context.PROVIDER_URL, server);
props.put("java.naming.factory.url.pkgs", "org.jnp.interfaces");
InitialContext ctx = new InitialContext(props);
Enumeration<NameClassPair> em=ctx.list("EmployeeManagement");
while(em.hasMoreElements())
{
NameClassPair obj=(NameClassPair)em.nextElement();
System.out.println("Next Element:"+obj.toString());
System.out.println("obj.getClassName()="+obj.getClassName());
System.out.println("obj.getName()="+obj.getName());
if(obj.getName().equalsIgnoreCase("EmployeeServiceBean"))
{
System.out.println("Hi Nitin inside EmployeeServiceBean..Yippee !");
Enumeration<NameClassPair> em2=ctx.list("EmployeeManagement/EmployeeServiceBean");
while(em2.hasMoreElements())
{
NameClassPair obj2=(NameClassPair)em2.nextElement();
System.out.println("Next Element Iteration 2:"+obj2.toString());
System.out.println("obj2.getClassName()="+obj2.getClassName());
System.out.println("obj2.getName()="+obj2.getName());
if(obj2.getName().equalsIgnoreCase("remote"))
{
employeeService=(EmployeeServiceRemote)ctx.lookup("EmployeeManagement/EmployeeServiceBean/"+obj2.getName());
System.out.println("Hi Nitin inside bootContainer...EmployeeServiceBean="+employeeService);
assertNotNull(employeeService);
}
}
}
}
}
protected void tearDown() throws Exception {
super.tearDown();
}
public void testFindEmployeeByEmployeeNumber() {
try{
Employee emp=employeeService.findEmployeeByEmployeeNumber("E001");
assertEquals("Abhishek", emp.getFirstName());
assertEquals("Pathak", emp.getLastName());
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
In above the EmployeeServiceRemote interface is the Remote interface which is being implemented by the stateless EJB: EmployeeServiceBean. The EmployeeManagement.ear is the name of the EAR file. Hence, I use "EmployeeManagement/EmployeeServiceBean/remote" for lookup. The EmployeeServiceBean has been annotated with @SecurityDomain("emLoginPolicy") annotation defined in org.jboss.annotation.security.SecurityDomain. First I'll show you what is the printed at the console and then we'll have a look at the Exception that I get while running the above test case.
Console Output first (given by Sysouts in the above test case):
Next Element:ItemAsSoldTestServiceBean: org.jnp.interfaces.NamingContext
obj.getClassName()=org.jnp.interfaces.NamingContext
obj.getName()=ItemAsSoldTestServiceBean
Next Element:EmployeeServiceBean: org.jnp.interfaces.NamingContext
obj.getClassName()=org.jnp.interfaces.NamingContext
obj.getName()=EmployeeServiceBean
Hi Nitin inside EmployeeServiceBean..Yippee !
Next Element Iteration 2:local: $Proxy113
obj2.getClassName()=$Proxy113
obj2.getName()=local
Next Element Iteration 2:remote: $Proxy112
obj2.getClassName()=$Proxy112
obj2.getName()=remote
If we have a look at the above console output we can see that there is an object in the JNDI tree which has the heirarchy EmployeeManagement-->EmployeeServiceBean-->remote. However, when we do a look-up by using the following line of code:
employeeService=(EmployeeServiceRemote)ctx.lookup("EmployeeManagement/EmployeeServiceBean/"+obj2.getName());
Then an exception is thrown.
When I run the above test case then I get the following exception:
java.lang.NoSuchFieldError: TRACE
at org.jboss.logging.Log4jLoggerPlugin.isTraceEnabled(Log4jLoggerPlugin.java:85)
at org.jboss.logging.Logger.isTraceEnabled(Logger.java:122)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:660)
at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:627)
at javax.naming.InitialContext.lookup(InitialContext.java:351)
at com.nit.ejb.session.employee.EmployeeServiceTest2.setUp(EmployeeServiceTest2.java:58)
at junit.framework.TestCase.runBare(TestCase.java:128)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:120)
at junit.framework.TestSuite.runTest(TestSuite.java:230)
at junit.framework.TestSuite.run(TestSuite.java:225)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
I get the above exception even if I remove the @SecurityDomain annotation from EmployeeServiceBean session bean and then try to run the given test case.
Request you to let me know the reason behind this problem and the possible solution for this.
Thank You !
Nitin