2 Replies Latest reply on Jul 10, 2013 7:23 AM by feijtel

    Multiple session beans with the same interface

    feijtel

      Hi,

       

      I've searched the website and also tried finding an answer in the EJB3 spec, but haven't been able to find an answer.

       

      Is it possible (is it even allowed??) to have multiple EJB3 session beans that implement the same interface?

       

      I'm currently migrating an application from JBoss 5 to JBoss 7.2.0 and running into the error: JBAS014546: more than one EJB found with a particular interface....

       

      I've made a simple example to show you what is being done in the code of the application:

       

      @Local

      public interface TestBean {

      }

       

      @Stateless

      @EJB(name = "java:global/coo/TestBean1", beanInterface = TestBean.class)

      public class TestBean1 implements TestBean{

      }

       

      @Stateless

      @EJB(name = "java:global/coo/TestBean2", beanInterface = TestBean.class)

      public class TestBean2 implements TestBean{

      }

       

      And the error I'm getting is this:

      12:51:46,310 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-8) MSC000001: Failed to start service jboss.deployment.subunit."coo-ear.ear"."coo-ejb-2.3.2-SNAPSHOT.jar".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.subunit."coo-ear.ear"."coo-ejb-2.3.2-SNAPSHOT.jar".INSTALL: JBAS018733: Failed to process phase INSTALL of subdeployment "coo-ejb-2.3.2-SNAPSHOT.jar" of deployment "coo-ear.ear"

          at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:127) [jboss-as-server-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]

          at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.4.GA-redhat-1.jar:1.0.4.GA-redhat-1]

          at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.4.GA-redhat-1.jar:1.0.4.GA-redhat-1]

          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_21]

          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_21]

          at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_21]

      Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: JBAS014546: More than one EJB found with interface of type 'nl.makelaarsuite.coo.test.TestBean' for binding java:global/coo/TestBean2. Found: [View of type nl.makelaarsuite.coo.test.TestBean for org.jboss.as.ejb3.component.stateless.StatelessComponentDescription{serviceName=service jboss.deployment.subunit."coo-ear.ear"."coo-ejb-2.3.2-SNAPSHOT.jar".component.TestBean2}@4c08702a, View of type nl.makelaarsuite.coo.test.TestBean for org.jboss.as.ejb3.component.stateless.StatelessComponentDescription{serviceName=service jboss.deployment.subunit."coo-ear.ear"."coo-ejb-2.3.2-SNAPSHOT.jar".component.TestBean1}@5335bcdf]

          at org.jboss.as.ejb3.deployment.processors.EjbInjectionSource.getResourceValue(EjbInjectionSource.java:97)

          at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.addJndiBinding(ModuleJndiBindingProcessor.java:251)

          at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor$1.handle(ModuleJndiBindingProcessor.java:196)

          at org.jboss.as.ee.component.ClassDescriptionTraversal.run(ClassDescriptionTraversal.java:54)

          at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.processClassConfigurations(ModuleJndiBindingProcessor.java:164)

          at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.deploy(ModuleJndiBindingProcessor.java:157)

          at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:120) [jboss-as-server-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]

          ... 5 more

       

      I can understand that it's not desirable to have the same interface being used on 2 session beans, but the interface in my application contains a number of methods and that interface is also used later on to perform actions on the session bean.

       

      A solution that works is to create a separate interface for each bean that inherit from the interface that has been used (TestBean in the example)...but in the application I'm migrating there are many beans that implement this interface, so that would require me to write a lot of "empty" interface classes just to get this work.

       

      I guess if the spec (or JBoss) doesn't allow it, I have no other choice. Just wondering if there is an accaptable solution...

       

      Any help is greatly appreciated. Thanks!

       

      Leon

        • 1. Re: Multiple session beans with the same interface
          jaikiran

          It's perfectly valid for multiple EJBs to implement the same interface. The error isn't because multiple EJBs are implementing the same interface, but it's because the usage of the @EJB in your application is such that the container has no idea which of the multiple EJB implementations you are trying to setup into the java:global namespace via the @EJB usage:

           

          @Stateless
          @EJB(name = "java:global/coo/TestBean1", beanInterface = TestBean.class)
          public class TestBean1 implements TestBean{
          }
          
          @Stateless
          @EJB(name = "java:global/coo/TestBean2", beanInterface = TestBean.class)
          public class TestBean2 implements TestBean{
          

           

          The spec allows you to narrow it down to the specific EJB implementation. You can do so by using the "beanName" attribute of the @EJB where you can specify the name of the bean (which by default is the bean implementation's simple class name). So you should change that above code to:

           

          @Stateless

          @EJB(name = "java:global/coo/TestBean1", beanInterface = TestBean.class, beanName="TestBean1")

          public class TestBean1 implements TestBean{

          }

           

          @Stateless

          @EJB(name = "java:global/coo/TestBean2", beanInterface = TestBean.class, beanName="TestBean2")

          public class TestBean2 implements TestBean{

          • 2. Re: Multiple session beans with the same interface
            feijtel

            Thank you very much, this does indeed solve the problem!