2
votes

I am exposing a singleton EJB as restful service; requirement is to initiate a timer via Rest API. As this is going to be web app, i am packing ejb class in war file. I am successfully able to deploy the bean and invoke the web service, but could not initiate the timer as @Resource annotation is not injecting SessionContext in the aforementioned singleton ejb (tried with stateless session bean as well). When debugged I see SessionContext object is null. Any suggestions on how I can make the timer service work in this scenario? Below are details:

  • JBoss 7.1.1 Final
  • RestEasy 2.3.7 Final
  • Java 7

TimerSessionBean.java:

import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Singleton;
import javax.ejb.Timer;
import javax.ejb.Timeout;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

@Singleton
@Path("/config")
public class TimerSessionBean {

   @Resource
   private SessionContext context;

   @GET
   @Path("{id}")
   public void createTimer(@PathParam("id") long duration) {
       context.getTimerService().createTimer(duration, "Hello World!");
   }

   @Timeout
   public void timeOutHandler(Timer timer) {
       System.out.println("timeoutHandler : " + timer.getInfo());       
   }
}

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <listener>
        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
    </listener>
    <filter>
      <filter-name>ShiroFilter</filter-name>
      <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
    </filter>
    <filter-mapping>
       <filter-name>ShiroFilter</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>
 </web-app>

AppConfig.java:

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/")
public class AppConfig extends Application {

    @Override
    @SuppressWarnings("unchecked")
    public Set<Class<?>> getClasses() {
         Set<Class<?>> set = new HashSet<Class<?>>();
         set.add(TimerSessionBean.class);
         return set;
    }
}

Excerpt from server log:

20:09:08,850 INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-1) JNDI bindings for session bean named TimerSessionBean in deployment unit deployment "myapp-1.0.war" are as follows:
    java:global/myapp-1.0/TimerSessionBean!app.ws.resources.TimerSessionBean
java:app/myapp-1.0/TimerSessionBean!app.ws.resources.TimerSessionBean
java:module/TimerSessionBean!app.ws.resources.TimerSessionBean
java:global/myapp-1.0/TimerSessionBean
java:app/myapp-1.0/TimerSessionBean
java:module/TimerSessionBean
1

1 Answers

1
votes

You are packaging your ejb inside a war file, which implies that your are using EJB 3.1 Lite that is a reduced set of ejb features. I'm not sure why the SessionContext instance is not injected, but take in mind that the TimerService is not available in this reduced version of ejb specification.