title: Testing ejb with stub and openejb framework
body: <p>I am trying to test an EJB that have another one injected in it. 
  For the tests purpose I want to use a stub for the injected EJB. I had use openEJB as framework for the EJB for the testing. </p>
  
  <p>Here is the EJB :</p>
  
  <pre><code>@Stateless
  @Local(IService.class)
  public class Service implements IService {
  
      @EJB
      private IBean bean;
  
      @Override
      public String doService(String data) {
          return bean.process(data);
      }
  }
  </code></pre>
  
  <p>The real injected EJB :</p>
  
  <pre><code>@Stateless
  @Local(IBean.class)
  public class Bean implements IBean {
  
      private static Logger logger = Logger.getLogger(Bean.class);
  
      @Override
      public String process(String data) {
          logger.info("Bean processing : " + data);
          return "Bean processing : " + data;
      }
  }
  </code></pre>
  
  <p>The stub version of the EJB :</p>
  
  <pre><code>@Stateless
  @Local(IBean.class)
  public class BeanStub implements IBean {
  
      private static Logger logger = Logger.getLogger(BeanStub.class);
  
      @Override
      public String process(String data) {
          logger.info("Stub processing : " + data);
          return "Stub processing : " + data;
      }
  }
  </code></pre>
  
  <p>And the JUnit test used :</p>
  
  <pre><code>public class ServiceTest {
  
      private static Logger logger = Logger.getLogger(ServiceTest.class);
  
      private static InitialContext context;
  
      @BeforeClass
      public static void setUpBeforeClass() throws Exception {
          // openEJB
          Properties p = new Properties();
          p.put(Context.INITIAL_CONTEXT_FACTORY,"org.apache.openejb.client.LocalInitialContextFactory");
          p.put("openejb.altdd.prefix", "stub"); // use specific ejb-jar
          p.put("openejb.descriptors.output", "true");
  
          context = new InitialContext(p);
      }
  
      @Test
      public void testServiceStub() {
          try {
              IService service = (IService) context.lookup("ServiceStubLocal");
              assertNotNull(service);
              String msg = service.doService("service");
              assertEquals("Stub processing : service", msg);
          } catch (NamingException e) {
              logger.error(e);
              fail(e.getMessage());
          }
      }
  }
  </code></pre>
  
  <p>I had try to override the use of the real EJB by the stub one, using a specific ejb-jar (I want to use "BeanStub" instead of default "Bean" in my service) :</p>
  
  <pre><code> &lt;ejb-jar&gt;
      &lt;enterprise-beans&gt;
      &lt;session id="ServiceStub"&gt;
          &lt;ejb-name&gt;ServiceStub&lt;/ejb-name&gt;
          &lt;ejb-class&gt;tests.Service&lt;/ejb-class&gt;
          &lt;ejb-local-ref&gt;
              &lt;ejb-ref-name&gt;tests.Service/bean&lt;/ejb-ref-name&gt;
              &lt;ejb-link&gt;BeanStub&lt;/ejb-link&gt;
          &lt;/ejb-local-ref&gt;
      &lt;/session&gt;          
      &lt;/enterprise-beans&gt;
  &lt;/ejb-jar&gt; 
  </code></pre>
  
  <p>Unfortunatly I have a problem the EJB are declared :</p>
  
  <pre>
      Apache OpenEJB 3.1.4    build: 20101112-03:32
  http://openejb.apache.org/
  17:14:29,225  INFO startup:70 - openejb.home = D:\Workspace_Java\tests\testejb
  17:14:29,225  INFO startup:70 - openejb.base = D:\Workspace_Java\tests\testejb
  17:14:29,350  INFO config:70 - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
  17:14:29,350  INFO config:70 - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
  17:14:29,381  INFO config:70 - Found EjbModule in classpath: D:\Workspace_Java\tests\testejb\target\test-classes
  17:14:29,412  INFO config:70 - Found EjbModule in classpath: D:\Workspace_Java\tests\testejb\target\classes
  17:14:29,428  INFO config:70 - Beginning load: D:\Workspace_Java\tests\testejb\target\test-classes
  17:14:29,428  INFO config:70 - AltDD ejb-jar.xml -> file:/D:/Workspace_Java/tests/testejb/target/test-classes/META-INF/stub.ejb-jar.xml
  17:14:29,850  INFO config:70 - Beginning load: D:\Workspace_Java\tests\testejb\target\classes
  17:14:29,850  INFO config:70 - AltDD ejb-jar.xml -> file:/D:/Workspace_Java/tests/testejb/target/classes/META-INF/stub.ejb-jar.xml
  17:14:29,850  INFO config:70 - Configuring enterprise application: classpath.ear
  17:14:29,912  INFO config:70 - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container)
  17:14:29,912  INFO config:70 - Auto-creating a container for bean ServiceStub: Container(type=STATELESS, id=Default Stateless Container)
  17:14:29,912  INFO options:70 - Using 'openejb.descriptors.output=true'
  17:14:29,912  INFO options:70 - Using 'openejb.descriptors.output=true'
  17:14:29,928  INFO config:70 - Dumping Generated ejb-jar.xml to: C:\TEMP\ejb-jar-6391test-classes.xml
  17:14:29,959  INFO config:70 - Dumping Generated openejb-jar.xml to: C:\TEMP\openejb-jar-6392test-classes.xml
  17:14:29,959  INFO options:70 - Using 'openejb.descriptors.output=true'
  17:14:29,959  INFO config:70 - Dumping Generated ejb-jar.xml to: C:\TEMP\ejb-jar-6393classes.xml
  17:14:29,975  INFO config:70 - Dumping Generated openejb-jar.xml to: C:\TEMP\openejb-jar-6394classes.xml
  17:14:30,006  INFO config:70 - Enterprise application "classpath.ear" loaded.
  17:14:30,084  INFO startup:70 - Assembling app: classpath.ear
  17:14:30,131  INFO startup:70 - Jndi(name=ServiceStubLocal) --> Ejb(deployment-id=ServiceStub)
  17:14:30,131 ERROR startup:46 - Jndi name could not be bound; it may be taken by another ejb.  Jndi(name=openejb/Deployment/ServiceStub/tests.IService!Local)
  17:14:30,131  INFO startup:70 - Undeploying app: classpath.ear
  17:14:30,147 ERROR startup:50 - Application could not be deployed:  classpath.ear
  org.apache.openejb.OpenEJBException: Creating application failed: classpath.ear: Unable to bind business local interface for deployment ServiceStub
      at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:679)
      at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:450)
  </pre>
  
  <p>Is there something wrong in the approach, or in the way to write the ejb-jar ? </p>