1 Reply Latest reply on Jun 16, 2010 10:29 PM by snacker

    Getting an EJB session bean which uses @SecurityDomain annotation, in a unit test case through JNDI

    nitin.bhardwaj21

      Hi 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

        • 1. Re: Getting an EJB session bean which uses @SecurityDomain annotation, in a unit test case through JNDI
          snacker

          I have seen this problem when using JBoss 5.1.0 with JRun4.

           

          The problem we found was JRun4 includes an older version of log4j.

           

          The JBoss classes are coded to the newer version of log4j and are using the TRACE constant.

           

          To fix this we had to find all of the jars (turned out to be only 1) which contained the older log4j classes and remove them.

           

          We then used the latest version of the log4j jar.

           

          That fixed it in our case.

           

           

          So in your case it is likely that eclipse or the junit libraries (or classpath) it uses to run the tests have an older version of log4j.