1 Reply Latest reply on Feb 1, 2012 6:54 PM by Julie H

    ClassCastException with Quartz Servlet and EJBInvokerJob in Jboss 6

    Julie H Newbie

      Hi All.

      I am currently trying to get a Scheduled Quartz Job to run within JBoss 6.1.0.Final.

       

      I initially had Quartz running as a service in JBoss, however after many days of trying to get it running correctly(class loading issues), I decided to try removing the Quartz service and distribute Quartz within my application ear.

       

      I am initiating the Scheduler via a servlet, which seems to be working ok.

       

      My problem arises when the Job I try to schedule is in an EJB.

       

      I can successfully schedule a job which is NOT in an EJB. (I just have a simple class which implements the Job class), but when attempting to schedule a job which is in an EJB, then I get the following ClassCastException :

       

      2012-01-30 15:46:00,055 ERROR [org.quartz.core.ErrorLogger] (DefaultQuartzScheduler_Worker-3) Job (My Test Job.Test Quartz Job threw an exception.: org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: java.lang.ClassCastException]
           at org.quartz.core.JobRunShell.run(JobRunShell.java:234) [:]
           at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549) [:]
      Caused by: java.lang.ClassCastException
           at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229) [:1.6.0_16]
           at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137) [:1.6.0_16]
           at org.quartz.jobs.ee.ejb.EJBInvokerJob.execute(EJBInvokerJob.java:163) [:]
           at org.quartz.core.JobRunShell.run(JobRunShell.java:223) [:]
           ... 1 more
      Caused by: java.lang.ClassCastException: $Proxy149 cannot be cast to org.omg.CORBA.Object
           at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:212) [:1.6.0_16]
           ... 4 more
      
      
      

       

      Here is the init method of the servlet :

       

      public void init(ServletConfig config) throws ServletException {
      
           System.out.println("ChannelToolsSchedulingServlet - Scheduling Job ..");
      
           try {
         
                String ejbJNDI = config.getInitParameter("EJBJNDI");
                System.out.println("ChannelToolsSchedulingServlet - EJBJNDI = " + ejbJNDI);
      
                String ejbMethod = config.getInitParameter("EJBMethod");
                System.out.println("ChannelToolsSchedulingServlet - EJBMethod = " + ejbMethod);
         
                JobDetail jd = new JobDetail("Test Quartz Job","My Test Job",EJBInvokerJob.class);
                jd.getJobDataMap().put("ejb", ejbJNDI);
                jd.getJobDataMap().put("method", ejbMethod);
                Object[] jdArgs = new Object[0];
                jd.getJobDataMap().put("args", jdArgs);
         
         
                CronTrigger cronTrigger = new CronTrigger("CronTrigger1", "CronTrigger1");
                String cronExpr = null;
                // Get the cron Expression as an Init parameter
                cronExpr = config.getInitParameter("CronExpression");
                System.out.println("ChannelToolsSchedulingServlet - CronExpression = " + cronExpr);
                cronTrigger.setCronExpression(cronExpr);
           
                Scheduler sched = StdSchedulerFactory.getDefaultScheduler();
                sched.scheduleJob(jd, cronTrigger);
                System.out.println("ChannelToolsSchedulingServlet - Job scheduled now ..");
           } 
           catch (Exception e) {
                e.printStackTrace();
           }
        
      }
      

       

      Here is the relevant bits from my web.xml

       

                           
      
            <servlet>
               <servlet-name>QuartzInitializer</servlet-name>
               <display-name>Quartz Initializer Servlet</display-name>
               <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
               <init-param>
                   <param-name>shutdown-on-unload</param-name>
                   <param-value>true</param-value>
               </init-param>
               <init-param>
                   <param-name>start-scheduler-on-load</param-name>
                   <param-value>true</param-value>
               </init-param>
               <load-on-startup>1</load-on-startup>
            </servlet>
            <!-- schedule the EJB job -->
            <servlet>
              <servlet-name>ResendSchedulingServlet</servlet-name>
              <display-name>ResendSchedulingServlet</display-name>
              <servlet-class>com.company.channels.tools.ChannelToolsSchedulingServlet</servlet-class>
              <init-param>
                <param-name>CronExpression</param-name>
                <param-value>0 0/1 * * * ?</param-value>
              </init-param>
              <init-param>
                <param-name>EJBMethod</param-name>
                <param-value>processRetryDirectory</param-value>
              </init-param>
              <init-param>
                <param-name>EJBJNDI</param-name>
                <param-value>AMIResend/remote</param-value>
              </init-param>
              <load-on-startup>2</load-on-startup>
            </servlet>
            <!-- schedule the NON-EJB job -->
            <servlet>
              <servlet-name>TestSchedulingServlet</servlet-name>
              <display-name>TestSchedulingServlet</display-name>
              <servlet-class>com.company.channels.tools.TestSchedulingServlet</servlet-class>
              <init-param>
                <param-name>CronExpression</param-name>
                <param-value>0 0/1 * * * ?</param-value>
              </init-param>
              <load-on-startup>2</load-on-startup>
            </servlet>
      
      

       

       

      I have tried using both the remote and local interface of my EJB, both are installed as per following Jboss logging :

       

      2012-01-30 15:44:49,224 INFO  [org.jboss.ejb3.session.SessionSpecContainer] (Thread-2) Starting jboss.j2ee:ear=Channels.ear,jar=Channels-Ejb.jar,name=AMIResend,service=EJB3
      2012-01-30 15:44:49,240 INFO  [org.jboss.ejb3.EJBContainer] (Thread-2) STARTED EJB: com.company.channel.ejb.process.AMIResendEJB ejbName: AMIResend
      2012-01-30 15:44:49,506 INFO  [org.jboss.ejb3.proxy.impl.jndiregistrar.JndiSessionRegistrarBase] (Thread-2) Binding the following Entries in Global JNDI:
      
           AMIResend/remote - EJB3.x Default Remote Business Interface
           Channels/AMIResend/remote-com.company.channel.ejb.process.interfaces.AMIResendRemote - EJB3.x Remote Business Interface
           AMIResend/local - EJB3.x Default Local Business Interface
           Channels/AMIResend/local-com.company.channel.ejb.process.interfaces.AMIResendLocal - EJB3.x Local Business Interface
      
      
      

       

      Here is the EJB class and relevant interfaces

       

      package com.company.channel.ejb.process;
        import javax.ejb.Stateless;
        import javax.ejb.TransactionManagement;
        import javax.ejb.TransactionManagementType;
        import org.jboss.ejb3.annotation.LocalBinding;
        import org.jboss.ejb3.annotation.RemoteBinding;
        import com.company.channel.ejb.process.interfaces.AMIResendRemote;
        import com.company.channel.ejb.process.interfaces.AMIResendLocal;
        import javax.ejb.EJBException;
        
        @LocalBinding(jndiBinding="AMIResend/local")
        @RemoteBinding(jndiBinding="AMIResend/remote")
        
        @Stateless (name="AMIResend"   ,mappedName="ejb/company/axis/AMIResend")
        @TransactionManagement(TransactionManagementType.BEAN)
        
        public class AMIResendEJB implements AMIResendRemote,AMIResendLocal {
        
           private javax.ejb.SessionContext mySessionCtx;
        
           public AMIResendEJB() {
               System.out.println("Calling AMIResendEJB constructor");
           }
      
           public javax.ejb.SessionContext getSessionContext() {
              return mySessionCtx;
           }
        
      
           public void setSessionContext(javax.ejb.SessionContext ctx) {
              mySessionCtx = ctx;
           }
        
          public void processRetryDirectory() throws EJBException {
        
               System.out.println("running the processRetryDirectory method of AMIResendEJB");
        
          }
        }
      

       

       

      package com.company.channel.ejb.process.interfaces;
      
      import javax.ejb.Local;
      
      
      @Local
      
      public interface AMIResendLocal extends AMIResend {
      }
      

       

       

       

      package com.company.channel.ejb.process.interfaces;
      
      import javax.ejb.Remote;
      
      
      @Remote
      
      public interface AMIResendRemote extends AMIResend {
      
      }
      
      

       

       

       

      package com.company.channel.ejb.process.interfaces;
      
      import javax.ejb.EJBException;
      
      
      public interface AMIResend {
      
        public void processRetryDirectory() throws EJBException;
      }
      

       

       

       

      The non-ejb job which works is just a simple 'Hello World' class, so I didn't include the code.

       

      The output from my logging is as follows :

      2012-01-30 15:44:52,474 INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/channel]] (Thread-2) QuartzInitializer: Quartz Initializer Servlet loaded, initializing Scheduler...
      2012-01-30 15:44:52,490 INFO  [org.quartz.impl.StdSchedulerFactory] (Thread-2) Using default implementation for ThreadExecutor
      2012-01-30 15:44:52,490 INFO  [org.quartz.simpl.SimpleThreadPool] (Thread-2) Job execution threads will use class loader of thread: Thread-2
      2012-01-30 15:44:52,521 INFO  [org.quartz.core.SchedulerSignalerImpl] (Thread-2) Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
      2012-01-30 15:44:52,521 INFO  [org.quartz.core.QuartzScheduler] (Thread-2) Quartz Scheduler v.1.8.6 created.
      2012-01-30 15:44:52,521 INFO  [org.quartz.simpl.RAMJobStore] (Thread-2) RAMJobStore initialized.
      2012-01-30 15:44:52,521 INFO  [org.quartz.core.QuartzScheduler] (Thread-2) Scheduler meta-data: Quartz Scheduler (v1.8.6) 'DefaultQuartzScheduler' with instanceId 'NON_CLUSTERED'
        Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
        NOT STARTED.
        Currently in standby mode.
        Number of jobs executed: 0
        Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
        Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
      
      2012-01-30 15:44:52,521 INFO  [org.quartz.impl.StdSchedulerFactory] (Thread-2) Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'
      2012-01-30 15:44:52,521 INFO  [org.quartz.impl.StdSchedulerFactory] (Thread-2) Quartz scheduler version: 1.8.6
      2012-01-30 15:44:52,521 INFO  [org.quartz.core.QuartzScheduler] (Thread-2) Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
      2012-01-30 15:44:52,521 INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/channel]] (Thread-2) QuartzInitializer: Scheduler has been started...
      2012-01-30 15:44:52,521 INFO  [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/channel]] (Thread-2) QuartzInitializer: Storing the Quartz Scheduler Factory in the servlet context at key: org.quartz.impl.StdSchedulerFactory.KEY
      2012-01-30 15:44:52,552 INFO  [STDOUT] (Thread-2) TestSchedulingServlet - Scheduling Job ..
      
      2012-01-30 15:44:52,552 INFO  [STDOUT] (Thread-2) TestSchedulingServlet - CronExpression = 0 0/1 * * * ?
      
      2012-01-30 15:44:52,677 INFO  [STDOUT] (Thread-2) TestSchedulingServlet - Job scheduled now ..
      
      2012-01-30 15:44:52,693 INFO  [STDOUT] (Thread-2) ChannelToolsSchedulingServlet - Scheduling Job ..
      
      2012-01-30 15:44:52,693 INFO  [STDOUT] (Thread-2) ChannelToolsSchedulingServlet - EJBJNDI = AMIResend/remote
      
      2012-01-30 15:44:52,709 INFO  [STDOUT] (Thread-2) ChannelToolsSchedulingServlet - EJBMethod = processRetryDirectory
      
      2012-01-30 15:44:52,709 INFO  [STDOUT] (Thread-2) ChannelToolsSchedulingServlet - CronExpression = 0 0/1 * * * ?
      
      2012-01-30 15:44:52,709 INFO  [STDOUT] (Thread-2) ChannelToolsSchedulingServlet - Job scheduled now ..
      
      2012-01-30 15:44:52,803 INFO  [org.apache.coyote.http11.Http11Protocol] (Thread-2) Starting Coyote HTTP/1.1 on http-127.0.0.1-8080
      2012-01-30 15:44:52,818 INFO  [org.apache.coyote.ajp.AjpProtocol] (Thread-2) Starting Coyote AJP/1.3 on ajp-127.0.0.1-8009
      2012-01-30 15:44:52,818 INFO  [org.jboss.bootstrap.impl.base.server.AbstractServer] (Thread-2) JBossAS [6.1.0.Final "Neo"] Started in 2m:769ms
      2012-01-30 15:44:53,521 DEBUG [org.quartz.utils.UpdateChecker] (Timer-1) Checking for available updated version of Quartz...
      2012-01-30 15:45:00,021 DEBUG [org.quartz.simpl.SimpleJobFactory] (DefaultQuartzScheduler_QuartzSchedulerThread) Producing instance of Job 'SampleJob.SampleJob', class=com.company.channels.tools.SampleJob
      2012-01-30 15:45:00,037 DEBUG [org.quartz.core.JobRunShell] (DefaultQuartzScheduler_Worker-1) Calling execute on job SampleJob.SampleJob
      2012-01-30 15:45:00,068 DEBUG [org.quartz.simpl.SimpleJobFactory] (DefaultQuartzScheduler_QuartzSchedulerThread) Producing instance of Job 'My Test Job.Test Quartz Job', class=org.quartz.jobs.ee.ejb.EJBInvokerJob
      2012-01-30 15:45:00,053 INFO  [STDOUT] (DefaultQuartzScheduler_Worker-1) Hello World! - Mon Jan 30 15:45:00 EST 2012
      
      2012-01-30 15:45:00,100 DEBUG [org.quartz.core.JobRunShell] (DefaultQuartzScheduler_Worker-2) Calling execute on job My Test Job.Test Quartz Job
      2012-01-30 15:45:00,459 ERROR [org.quartz.core.JobRunShell] (DefaultQuartzScheduler_Worker-2) Job My Test Job.Test Quartz Job threw an unhandled Exception: : java.lang.ClassCastException
           at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229) [:1.6.0_16]
           at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137) [:1.6.0_16]
           at org.quartz.jobs.ee.ejb.EJBInvokerJob.execute(EJBInvokerJob.java:163) [:]
           at org.quartz.core.JobRunShell.run(JobRunShell.java:223) [:]
           at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549) [:]
      Caused by: java.lang.ClassCastException: $Proxy149 cannot be cast to org.omg.CORBA.Object
           at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:212) [:1.6.0_16]
           ... 4 more
      
      2012-01-30 15:45:00,459 ERROR [org.quartz.core.ErrorLogger] (DefaultQuartzScheduler_Worker-2) Job (My Test Job.Test Quartz Job threw an exception.: org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: java.lang.ClassCastException]
           at org.quartz.core.JobRunShell.run(JobRunShell.java:234) [:]
           at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549) [:]
      Caused by: java.lang.ClassCastException
           at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229) [:1.6.0_16]
           at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137) [:1.6.0_16]
           at org.quartz.jobs.ee.ejb.EJBInvokerJob.execute(EJBInvokerJob.java:163) [:]
           at org.quartz.core.JobRunShell.run(JobRunShell.java:223) [:]
           ... 1 more
      Caused by: java.lang.ClassCastException: $Proxy149 cannot be cast to org.omg.CORBA.Object
           at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:212) [:1.6.0_16]
           ... 4 more
      
      2012-01-30 15:46:00,008 DEBUG [org.quartz.simpl.SimpleJobFactory] (DefaultQuartzScheduler_QuartzSchedulerThread) Producing instance of Job 'My Test Job.Test Quartz Job', class=org.quartz.jobs.ee.ejb.EJBInvokerJob
      2012-01-30 15:46:00,039 DEBUG [org.quartz.core.JobRunShell] (DefaultQuartzScheduler_Worker-3) Calling execute on job My Test Job.Test Quartz Job
      2012-01-30 15:46:00,039 DEBUG [org.quartz.simpl.SimpleJobFactory] (DefaultQuartzScheduler_QuartzSchedulerThread) Producing instance of Job 'SampleJob.SampleJob', class=com.company.channels.tools.SampleJob
      2012-01-30 15:46:00,039 DEBUG [org.quartz.core.JobRunShell] (DefaultQuartzScheduler_Worker-4) Calling execute on job SampleJob.SampleJob
      2012-01-30 15:46:00,039 INFO  [STDOUT] (DefaultQuartzScheduler_Worker-4) Hello World! - Mon Jan 30 15:46:00 EST 2012
      
      2012-01-30 15:46:00,055 ERROR [org.quartz.core.JobRunShell] (DefaultQuartzScheduler_Worker-3) Job My Test Job.Test Quartz Job threw an unhandled Exception: : java.lang.ClassCastException
           at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229) [:1.6.0_16]
           at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137) [:1.6.0_16]
           at org.quartz.jobs.ee.ejb.EJBInvokerJob.execute(EJBInvokerJob.java:163) [:]
           at org.quartz.core.JobRunShell.run(JobRunShell.java:223) [:]
           at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549) [:]
      Caused by: java.lang.ClassCastException: $Proxy149 cannot be cast to org.omg.CORBA.Object
           at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:212) [:1.6.0_16]
           ... 4 more
      
      2012-01-30 15:46:00,055 ERROR [org.quartz.core.ErrorLogger] (DefaultQuartzScheduler_Worker-3) Job (My Test Job.Test Quartz Job threw an exception.: org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: java.lang.ClassCastException]
           at org.quartz.core.JobRunShell.run(JobRunShell.java:234) [:]
           at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:549) [:]
      Caused by: java.lang.ClassCastException
           at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:229) [:1.6.0_16]
           at javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:137) [:1.6.0_16]
           at org.quartz.jobs.ee.ejb.EJBInvokerJob.execute(EJBInvokerJob.java:163) [:]
           at org.quartz.core.JobRunShell.run(JobRunShell.java:223) [:]
           ... 1 more
      Caused by: java.lang.ClassCastException: $Proxy149 cannot be cast to org.omg.CORBA.Object
           at com.sun.corba.se.impl.javax.rmi.PortableRemoteObject.narrow(PortableRemoteObject.java:212) [:1.6.0_16]
           ... 4 more
      
      
      

       

       

       

      So as can be seen, the scheduler seems to be running.
      It says that it has scheduled the jobs, and does attempt to run them both every minute.
      The non-EJB job runs successfully, yet the EJB job gets the class cast exception.

       

      Any pointers on how to solve this issue, or things to try would be greatly appreciated.

       

      Thanks.

       

      Julie