5 Replies Latest reply on Jul 7, 2009 12:02 PM by alen_ribic

    How to inject EJB into POJO

    alen_ribic

      I have jboss-spring 3.2CR1 deployer configured on my JBoss 5.0.1GA server. I can confirm that my jboss-spring.xml file in my myapp.ear/myejb.jar/META-INF/ is loaded sucessfully with no errors.

      How do I inject an EJB, that is defined in my jboss-spring.xml, into a POJO? (Both the EJB and POJO are define in my myapp.ear/myejb.jar/)
      I have tried @Spring and got a NPE.

      thx,
      -Alen

        • 1. Re: How to inject EJB into POJO
          marius.bogoevici

          Alen,

          You can try using one of the standard Spring mechanisms:

          - org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean or the jee namespace
          - the @EJB annotation

          There is a sample showing the usage of the EJB annotation in https://anonsvn.jboss.org/repos/jbossas/projects/spring-int/trunk/documentation/samples/horoscope/horoscope-war/src/main/java/org/jboss/tutorial/web/AppController.java - the root of the sample is

          https://anonsvn.jboss.org/repos/jbossas/projects/spring-int/trunk/documentation/samples/horoscope/

          The difference between this and your scenario is that yours is injecting EJBs in a Spring-Deployer bootstrapped application context, whereas the sample is injecting them in an ApplicationContext bootstrapped by the ContextLoaderListener, but this should work pretty much the same.

          Give it a try and let me know if you encounter any issues.

          Marius

          • 2. Re: How to inject EJB into POJO
            marius.bogoevici

            Also, make sure that you use the <context:annotation-config/> namespace element in your Spring configuration, and make sure you don't have circular dependencies ala EJB->SpringBean->EJB etc, which would make the process of creating the components pretty awkward.

            As a note, @Spring is a JBoss-specific annotation used for injecting SpringDeployer-created beans into EJBs but it does not work the other way around.

            Cheers,
            Marius

            • 3. Re: How to inject EJB into POJO
              marius.bogoevici

              OK,

              I gave it a quick try. There is a problem with scenarios which imply a circular dependency between the EJBs and the Spring Deployer.

              If the Spring Bean depends on an EJB that needs to be injected with another Spring Bean from the same ApplicationContext, an initialization failure is to be expected, because the EJB cannot be initialized (can't find the ApplicationContext in JNDI, its creation is not finalized yet) which in turns causes the ApplicationContext creation to fail (EJB can't be injected in Spring bean).

              However, if the Spring bean depends on an EJB that is not dependent on another Spring bean, then all should work fine.


              Hope that helps,
              Marius

              • 4. Re: How to inject EJB into POJO
                alen_ribic

                 

                "marius.bogoevici" wrote:
                Alen,

                You can try using one of the standard Spring mechanisms:

                - org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean or the jee namespace
                - the @EJB annotation

                There is a sample showing the usage of the EJB annotation in https://anonsvn.jboss.org/repos/jbossas/projects/spring-int/trunk/documentation/samples/horoscope/horoscope-war/src/main/java/org/jboss/tutorial/web/AppController.java - the root of the sample is

                https://anonsvn.jboss.org/repos/jbossas/projects/spring-int/trunk/documentation/samples/horoscope/

                The difference between this and your scenario is that yours is injecting EJBs in a Spring-Deployer bootstrapped application context, whereas the sample is injecting them in an ApplicationContext bootstrapped by the ContextLoaderListener, but this should work pretty much the same.

                Give it a try and let me know if you encounter any issues.

                Marius


                Thx for your reply.

                I tried adding the @EJB to my POJO and still got a NPE.

                I will try explain the exact scenario on my end:

                jboss-spring.xml

                <?xml version="1.0" encoding="UTF-8"?>
                <beans xmlns="http://www.springframework.org/schema/beans"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:context="http://www.springframework.org/schema/context"
                 xmlns:jee="http://www.springframework.org/schema/jee"
                 xmlns:util="http://www.springframework.org/schema/util"
                 xmlns:tx="http://www.springframework.org/schema/tx"
                 xmlns:aop="http://www.springframework.org/schema/aop"
                 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
                 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
                 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
                 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
                 <context:annotation-config/>
                
                 <jee:jndi-lookup id="userServiceLookup" jndi-name="InspecApplication/UserServiceBean/local"/>
                 <jee:jndi-lookup id="projectServiceLookup" jndi-name="InspecApplication/ProjectServiceBean/local"/>
                 <jee:jndi-lookup id="generalServiceLookup" jndi-name="InspecApplication/GeneralServiceBean/local"/>
                 <jee:jndi-lookup id="milestoneServiceLookup" jndi-name="InspecApplication/MilestoneServiceBean/local"/>
                 <jee:jndi-lookup id="taskServiceLookup" jndi-name="InspecApplication/TaskServiceBean/local"/>
                 <jee:jndi-lookup id="eventServiceLookup" jndi-name="InspecApplication/EventServiceBean/local"/>
                
                 <bean id="backendManager" name="/inspecbackend/BackendManager"
                 class="com.eluminary.inspec.backend.BackendManager">
                 <property name="userService" ref="userServiceLookup" />
                 <property name="projectService" ref="projectServiceLookup" />
                 <property name="generalService" ref="generalServiceLookup" />
                 <property name="milestoneService" ref="milestoneServiceLookup" />
                 <property name="taskService" ref="taskServiceLookup" />
                 <property name="eventService" ref="eventServiceLookup" />
                 </bean>
                
                 <bean id="commandTaskStart" class="com.eluminary.inspec.backend.command.task.CommandTaskStart">
                 <property name="backendManager" ref="backendManager" />
                 </bean>
                 ...
                </beans>
                


                JEE Interceptor that intercepts methods on my Session Bean.
                StartTaskEvent.java

                public class StartTaskEvent extends BaseEventInterceptor {
                 private Log log = LogFactory.getLog(getClass());
                
                 @EJB private TaskService taskService;
                
                 @AroundInvoke
                 public Object handleEvent(InvocationContext ctx) throws Exception {
                 ActionEventHandler aeh = new TaskActionEventHandlerImpl();
                 Long taskId = (Long)ctx.proceed();
                 TaskEvent te = new TaskEvent();
                 te.setTask(taskService.getTask(taskId));
                 te.setType(TaskEvent.TaskEventType.START);
                 aeh.actionPerformed(te);
                 return taskId;
                 }
                }
                



                TaskActionEventHandlerImpl.java (POJO)

                public class TaskActionEventHandlerImpl implements TaskActionEventHandler {
                
                 ...
                
                 public void onStart() {
                 Command cmd = new CommandTaskStart(taskEvent.getTask());
                 cmd.execute();
                 }
                
                 ...
                
                }
                


                CommandTaskStart.java (POJO):

                public class CommandTaskStart implements Command {
                 private Task task;
                 private BackendManager backendManager;
                
                 public BackendManager getBackendManager() {
                 return backendManager;
                 }
                
                 public void setBackendManager(BackendManager backendManager) {
                 this.backendManager = backendManager;
                 }
                
                 public CommandTaskStart(Task task) {
                 this.task = task;
                 }
                
                 public void execute() {
                 task.setStatus(TaskStatus.GREEN);
                 getBackendManager().getTaskService().updateTask(task);
                 }
                


                I basically want to springify the above code as much as possible.
                For instance, the Interceptor StartTaskEvent exposes the implementation of the ActionEventHandler called TaskActionEventHandlerImpl().

                So first problem here is how do I inject the TaskActionEventHandlerImpl into the StartTaskEvent Interceptor? @Spring I though might not work since its not an EJB. And it didn't work.

                Thanks,
                -Al

                • 5. Re: How to inject EJB into POJO
                  alen_ribic

                  Ok, I managed to successfuly springify my POJOs now and can confirm that jboss-spring deployer is working nicelly.

                  Is it possible to inject Spring Beans into @Interceptors?

                  I have Events that need to be executed after EJB business methods are called. (For Example: after createTask() business method is called, the onStart() event method in another class should be called.)