1 Reply Latest reply on Feb 19, 2009 10:13 AM by dolsen

    TimerService issues

    dolsen

      Hi!

      I'm setting some timers using EJB TimerService:

      @Stateless
      public class CommandBean implements CommandRemote
      {
       static Logger logger = Logger.getLogger(PlayerBean.class);
      
       @Resource TimerService timerService;
      
       public void scheduleCommand(Command command)
       {
       timerService.createTimer(command.getDuration(), command);
       }
      
       public void scheduleContinousCommand(Command command)
       {
       timerService.createTimer(command.getDuration(), command.getDuration(), command);
       }
      
       public Collection<Command> getCommands(long userId)
       {
       Collection<Command> commands = new ArrayList<Command>();
       for (Object object : timerService.getTimers())
       {
       Timer timer = (Timer) object;
      
       Command command = (Command) timer.getInfo();
       command.setTimeRemaining(timer.getTimeRemaining());
       if (command.getUserId() == userId)
       {
       commands.add(command);
       }
       }
      
       return commands;
       }
      
       @Timeout
       public void runCommand(Timer timer)
       {
       Command command = (Command) timer.getInfo();
      
       logger.debug("runCommand: Firing command for user: " + command.getUserId() + " " + command.getDescription());
      
       User user = null;
      
       System.setProperty("java.security.policy", "server.policy");
       if (System.getSecurityManager() == null)
       {
       System.setSecurityManager(new RMISecurityManager());
       }
      
       InitialContext jndiContext;
       try
       {
       jndiContext = getInitialContext();
       UserRemote userRef = (UserRemote) jndiContext.lookup("UserRemote");
       UserRemote dao = (UserRemote) PortableRemoteObject.narrow(userRef, UserRemote.class);
       user = dao.findUser(command.getUserId());
       logger.debug("runCommand: loading userId: " + user.getId());
       }
       catch (NamingException e)
       {
       logger.error("NamingException: ", e);
       }
      ...
       }
      
       public static InitialContext getInitialContext() throws NamingException
       {
       Properties properties = new Properties();
      
       properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, System.getProperty(Context.INITIAL_CONTEXT_FACTORY));
       properties.setProperty(Context.URL_PKG_PREFIXES, System.getProperty(Context.URL_PKG_PREFIXES));
       properties.setProperty(Context.PROVIDER_URL, "jnp://" + System.getProperty("providerHost") + ":1099");
      
       return new InitialContext(properties);
       }
      
      



      jboss.xml:
      <?xml version="1.0" encoding="UTF-8"?>
      <jboss>
       <enterprise-beans>
       <session>
       <ejb-name>UserBean</ejb-name>
       <jndi-name>UserRemote</jndi-name>
       </session>
       </enterprise-beans>
      </jboss
      


      JNDI view shows:

      +- UserRemote (class: Proxy for: com.feudalism.session.user.UserRemote)


      This works fine, and the times run at the expected time.

      The problem occurs when the server is restarted, or the application is redeployed.

      At this point, when the timer fires I get the following error:

      ervice=EJB3]) NamingException:
      javax.naming.NameNotFoundException: UserRemote not bound
      at org.jnp.server.NamingServer.getBinding(NamingServer.java:771)
      at org.jnp.server.NamingServer.getBinding(NamingServer.java:779)
      at org.jnp.server.NamingServer.getObject(NamingServer.java:785)
      at org.jnp.server.NamingServer.lookup(NamingServer.java:443)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:585)
      at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
      at sun.rmi.transport.Transport$1.run(Transport.java:153)
      at java.security.AccessController.doPrivileged(Native Method)
      at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
      at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:466)
      at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:707)
      at java.lang.Thread.run(Thread.java:595)
      at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
      at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
      at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
      at org.jnp.server.NamingServer_Stub.lookup(Unknown Source)
      at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:713)
      at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:673)
      at javax.naming.InitialContext.lookup(InitialContext.java:351)
      at com.feudalism.session.command.CommandBean.runCommand(CommandBean.java:89)


      This is running on JBoss_5_0_0_GA

      Any help is appreciated.

        • 1. Re: TimerService issues
          dolsen

          Seems like the Command bean is deployed before the User bean and that the @Timeout happens to early.

          I guess the beans are deployed in alphabetical order?

          Changing the name to XXXCommandBean fixed the issue...

          Any ways of controlling this other than changing names of classes?

          There are still some issues when firing the Timeout hook, but I will move over to the EJB forum for that.