3 Replies Latest reply: Jul 16, 2012 10:21 AM by Kalyan Pasupuleti-Oracle RSS

    EJB Timer creation Issue in Weblogic Cluster 10.3.5

    949042
      Hi,

      I need help to create an EJB3 Timer into an weblogic 10.3.5 cluster.

      My requirement is : the EJB component deployed in Weblogic server calls a business method at periodic intervals.

      For that I've created a ServletContextListener which at contextInitialized calls the startTimer method of my Stateless Session EJB.

      At the startTimer method of my EJB bean class, calls the EJB TimerService's createTimer method though the Stateless Session EJB SessionContext.
      However, this call is unable to create the timer and thows the null pointer exception at weblogic.ejb.container.timer.ClusteredEJBTimerManager. The details stack trace is:

      contextInitialized called
      Got Context::javax.naming.InitialContext@10e33ef
      messageExporterSessionEJB[BaseRemoteObject] home: weblogic.ejb.container.internal.StatelessEJBHomeIm
      pl@4039fb
      com.ms.service.messageexporter.ejb.session.MessageExporterSessionEJB_uebpsg_Impl: Entering start() meth
      od of MessageExporterSessionEJB.
      java.lang.NullPointerException
      at weblogic.ejb.container.timer.ClusteredEJBTimerManager.createTimer(ClusteredEJBTimerManage
      r.java:76)
      at weblogic.ejb.container.timer.ClusteredEJBTimerManager.createTimer(ClusteredEJBTimerManage
      r.java:95)
      at weblogic.ejb.container.internal.TimerServiceImpl.createTimer(TimerServiceImpl.java:125)
      at weblogic.ejb.container.internal.TimerServiceImpl.createTimer(TimerServiceImpl.java:49)
      at com.ms.service.messageexporter.ejb.session.MessageExporterSessionEJBBean.startTimer(MessageE
      xporterSessionEJBBean.java:131)
      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:597)
      at com.bea.core.repackaged.springframework.aop.support.AopUtils.invokeJoinpointUsingReflecti
      on(AopUtils.java:310)

      ....
      at com.bea.core.repackaged.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynami
      cAopProxy.java:204)
      at $Proxy78.startTimer(Unknown Source)
      at com.ms.service.messageexporter.ejb.session.MessageExporterSessionEJB_uebpsg_MessageExporterS
      essionEJBImpl.__WL_invoke(Unknown Source)
      at weblogic.ejb.container.internal.SessionRemoteMethodInvoker.invoke(SessionRemoteMethodInvo
      ker.java:40)
      at com.ms.service.messageexporter.ejb.session.MessageExporterSessionEJB_uebpsg_MessageExporterS
      essionEJBImpl.startTimer(Unknown Source)
      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:597)
      at weblogic.ejb.container.internal.RemoteBusinessIntfProxy.invoke(RemoteBusinessIntfProxy.ja
      va:85)
      at $Proxy76.startTimer(Unknown Source)
      at com.ms.service.messageexportlauncher.client.MessageExporterLauncher.contextInitialized
      (MessageExporterLauncher.java:54)
      at weblogic.servlet.internal.EventsManager$FireContextListenerAction.run(EventsManager.java:
      481)
      at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
      at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
      at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:181)
      .....

      I've deployed to cluster with two managed servers running in my a local domain.

      The code snippets of my implementation are :
      ================================================================
      1. ServletContextListener implementation:

      public class MessageExporterLauncher implements ServletContextListener {

      @EJB(name="MessageExporterSessionEJB", mappedName="MessageExporter-MessageExporterModel-MessageExporterSessionEJB")
      MessageExporterSessionEJB messageExporterSessionEJB;

      public void contextInitialized(ServletContextEvent event) {
      System.out.println("contextInitialized called");

      try {
      Context context = this.getContext();
      messageExporterSessionEJB.startTimer();
      } catch (Throwable ex) {
      ex.printStackTrace();
      }
      }

      public void contextDestroyed(ServletContextEvent event) {
      messageExporterSessionEJB.stopTimer();
      }

      private Context getContext() {
      Hashtable env = new Hashtable();
      env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
      env.put(Context.SECURITY_PRINCIPAL, "weblogic");
      env.put(Context.SECURITY_CREDENTIALS, "weblogic1");
      Context ctx = null;
      try {
      ctx = new InitialContext(env);
      } catch (NamingException e) {
      System.out.println("Error getting context due to::" + e.getCause());
      }
      System.out.println("Got Context::" + ctx);
      return ctx;
      }
      }

      1. Stateless Session EJB implementation:

      Remote interface:
      @Remote
      public interface MessageExporterSessionEJB {
      public void startTimer();
      public void stopTimer();
      }

      EJB Bean Implementation:

      @Startup
      @Stateless(name = "MessageExporterSessionEJB",
      mappedName = "MessageExporter-MessageExporterModel-MessageExporterSessionEJB")
      public class MessageExporterSessionEJBBean implements MessageExporterSessionEJB, MessageExporterSessionEJBLocal{

      @Resource
      private SessionContext sessionContext;

      private Timer timer;

      @Override
      public void startTimer() {
      System.out.println(this.getClass().getName() + ": Entering start() method of MessageExporterSessionEJB.");
      try {
      this.timer = sessionContext.getTimerService().createTimer(20000, 108000, null);
      } catch (Exception e) {
      e.printStackTrace();
      LogUtil.error(this.getClass(), "Cause::" + e.getCause());
      LogUtil.error(this.getClass(), "Message::" + e.getMessage());
      }
      }

      @Timeout
      public void handleTimeout(Timer timer) {
      System.out.println(this.getClass().getName() + ": HandleTimeout called.");
      try {
      //my business method call that has to be done at the periodic intervals
      catch (Exception e) {
      System.out.println(this.getClass().getName() + ": Error in handleTimeout due to::" + e.getCause());
      }
      }

      @Override
      public void stopTimer() {
      timer.cancel();
      System.out.println(this.getClass().getName() + ": Timer Stopped!");
      }
      }
      ================================================================
      Configuration changes in I've done for my cluster are:
      1. Under Cluster Configuration -> Migration tab:
           Migration Basis: Database
           Data Source For Automatic Migration: <my configured datasource name>
           Auto Migration Table Name: ACTIVE

      2. Under Cluster Configuration -> Scehduling tab:
           Data Source For Job Scheduler: <my configured datasource name>
           Job Scheduler Table Name: <db user/schema name>.WEBLOGIC_TIMERS

      I've created the WEBLOGIC_TIMERS table in the same schema as:

           CREATE TABLE WEBLOGIC_TIMERS (
           TIMER_ID VARCHAR2(100) NOT NULL,
           LISTENER BLOB NOT NULL,
           START_TIME NUMBER NOT NULL,
           INTERVAL NUMBER NOT NULL,
           TIMER_MANAGER_NAME VARCHAR2(100) NOT NULL,
           DOMAIN_NAME VARCHAR2(100) NOT NULL,
           CLUSTER_NAME VARCHAR2(100) NOT NULL,
           PRIMARY KEY (TIMER_ID, CLUSTER_NAME, DOMAIN_NAME)
           );

      Anyone have faced similar situation? Please help me.
        • 1. Re: EJB Timer creation Issue in Weblogic Cluster 10.3.5
          Kalyan Pasupuleti-Oracle
          Hi,

          Check this blog this will help you resolve your problem.

          https://blogs.oracle.com/jamesbayer/entry/a_simple_job_scheduler_example


          regards,
          Kal
          • 2. Re: EJB Timer creation Issue in Weblogic Cluster 10.3.5
            949042
            Hi Kalyan,

            I've followed as suggested by James. Still unable to create the timer. The stack trace is:
            contextInitialized called
            messageExporterSessionEJB::[BaseRemoteObject] home: weblogic.ejb.container.internal.StatelessEJBHome
            Impl@a7e2e
            com.ms.service.messageexporter.ejb.session.MessageExporterSessionEJB_uebpsg_Impl: Entering start() meth
            od of MessageExporterSessionEJB.
            com.ms.service.messageexporter.ejb.session.MessageExporterSessionEJB_uebpsg_Implthis.sessionContext::we
            blogic.ejb.container.deployer.SessionContextProxyImpl@1bfa3e4#########
            jobScheduler reference weblogic.scheduler.TimerServiceImpl@f6e9d
            java.lang.IllegalStateException: weblogic.scheduler.TimerException: Unable to create timer
            at weblogic.scheduler.TimerServiceImpl.schedule(TimerServiceImpl.java:78)
            at weblogic.timers.internal.commonj.TimerManagerImpl.schedule(TimerManagerImpl.java:158)
            at com.ms.service.messageexporter.ejb.session.MessageExporterSessionEJBBean.startTimer(MessageE
            xporterSessionEJBBean.java:116)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

            Code:

            *1. MessageExporterSessionEJB (Remote Interface):*

            import javax.ejb.Remote;

            @Remote
            public interface MessageExporterSessionEJB {

            public void startTimer();

            public void stopTimer();
            }

            *2. MessageExporterSessionEJBBean (Stateless Session EJB):*

            import commonj.timers.TimerManager;
            import commonj.timers.Timer;
            import commonj.timers.TimerListener;

            @Singleton
            @Stateless(name = "MessageExporterSessionEJB",
            mappedName = "EMessageExporter-MessageExporterModel-MessageExporterSessionEJB")
            public class MessageExporterSessionEJBBean implements MessageExporterSessionEJB, MessageExporterSessionEJBLocal, TimerListener {

            private Timer timer;
            private TimerManager jobScheduler;

            @Override
            public void startTimer() {
                 System.out.println(this.getClass().getName() + ": Entering start() method of MessageExporterSessionEJB.");
                 System.out.println(this.getClass().getName() + "this.sessionContext::" + this.sessionContext + "#########");
                 try {
            InitialContext ic = new InitialContext();
            jobScheduler = (TimerManager)ic.lookup("weblogic.JobScheduler");
            System.out.println("jobScheduler reference " + jobScheduler);
            jobScheduler.schedule(this, 0, 30 * 1000);
                 System.out.println(this.getClass().getName() + "Timer Created");
                 } catch (Exception e) {
            e.printStackTrace();
            System.out.println(this.getClass().getName() + "Cause::" + e.getCause());
            System.out.println(this.getClass().getName() + "Message::" + e.geMessage());
            }
            }

            @Override
            public void timerExpired(Timer timer) {
            System.out.println(this.getClass().getName() + ": timerExpired called.");
            try {
            getQueueMessages();
            }
            catch (Exception e) {
            System.out.println(this.getClass().getName() + ": Error in timerExpired due to::" + e.getCause());
            }
            }

            @Override
            public void stopTimer() {
            jobScheduler.stop();
            System.out.println(this.getClass().getName() + ": Timer Stopped!");
            }
            }

            *3. MessageExporterLauncher (ServletContextListener that is to trigger the EJB timer):*

            public class MessageExporterLauncher implements ServletContextListener {

            @EJB(name="MessageExporterSessionEJB", mappedName="MessageExporter-MessageExporterModel-MessageExporterSessionEJB")
            MessageExporterSessionEJB messageExporterSessionEJB;

            public void contextInitialized(ServletContextEvent event) {
            System.out.println("contextInitialized called");

                 try {          
                      System.out.println("messageExporterSessionEJB::" + messageExporterSessionEJB);
                      messageExporterSessionEJB.startTimer();
                 } catch (Throwable ex) {
                      ex.printStackTrace();
                 }
            }

            public void contextDestroyed(ServletContextEvent event) {
            LogUtil.info(this.getClass(), "contextDestroyed called");
            messageExporterSessionEJB.stopTimer();
            }
            }

            *4. weblogic-ejb-jar.xml:*
            <?xml version = '1.0' encoding = 'windows-1252'?>
            <weblogic-ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar http://xmlns.oracle.com/weblogic/weblogic-ejb-jar/1.1/weblogic-ejb-jar.xsd"
            xmlns="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar">
            <weblogic-enterprise-bean>
            <ejb-name>MessageExporterSessionEJB</ejb-name>
            <stateless-session-descriptor>
            <pool>
            <max-beans-in-free-pool>10</max-beans-in-free-pool>
            <initial-beans-in-free-pool>10</initial-beans-in-free-pool>
            </pool>
            <stateless-clustering>
            <home-is-clusterable>true</home-is-clusterable>
            <stateless-bean-is-clusterable>true</stateless-bean-is-clusterable>
            </stateless-clustering>
            </stateless-session-descriptor>
            <enable-call-by-reference>true</enable-call-by-reference>
            </weblogic-enterprise-bean>
            <timer-implementation>Clustered</timer-implementation>
            <disable-warning>BEA-010001</disable-warning>
            <disable-warning>BEA-010054</disable-warning>
            <disable-warning>BEA-010200</disable-warning>
            <disable-warning>BEA-010202</disable-warning>
            </weblogic-ejb-jar>

            Also, as suggested by James:
            1. have datasource for the user with executing the scripts scheduler.ddl and leasing.ddl successfully.
            2. Added the EJB Module jar, MessageExporterEJBModule.jar in the server classpath (setDomainEnv.cmd).

            Please let me know what I've missed?

            If anyone have successfully implemented in this way, please share me the details. Thanks in advance.
            • 3. Re: EJB Timer creation Issue in Weblogic Cluster 10.3.5
              Kalyan Pasupuleti-Oracle
              Hi,

              Try to clear cache and tmp folder and check again.

              If not open a SR with weblogic support.

              Might this would leads to BUG.

              Regards,
              Kal