Quartz Scheduler
jfrankman Aug 6, 2007 12:54 PMI have already posted this in the EJB3 forum, but since I am also using SEAM I thought that perhaps this problem has something to do with my SEAM configuration. I have a project deployed to JBoss 4.0.5 using SEAM 1.2. I know that SEAM 2.0 will support quartz scheduling, but I am trying to get this to work with SEAM 1.2. My problem is that I can get quartz to trigger my Job, but when it runs it cannot find META-INF/persistence.xml file. Somehow I need to be able to run a job that uses EJB3 and persistence from quartz. Below is a description of the problem. Does anyone see any problems with how I am tackling this? I am about to give up and just use cron, but I would really like to get this to work from the EAR application.
I am trying to use the quartz scheduler that comes with JBoss. I have created a simple job that logs a message every few minutes. Now that I have this working, I want to call a job that requires Hibernate and Java Persistence. When I do this I get errors because the persistence.xml file is not found in META-INF folder. I beleive this is a class path issue. Here is the error I am getting:
12:36:00,034 INFO [Ejb3Configuration] Could not find any META-INF/persistence.xml file in the classpath 12:36:00,034 WARN [UserSuppliedConnectionProvider] No connection properties specified - the user must supply JDBC connections 12:36:00,034 ERROR [JobRunShell] Job default.job.0.1186166057839 threw an unhandled Exception: javax.ejb.EJBTransactionRolledbackException: javax.persistence.PersistenceException: org.hibernate.HibernateException: Hibernate Dialect must be explicitly set at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:93) at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130) at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:195) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.ejb3.mdb.MessagingContainer.localInvoke(MessagingContainer.java:245) at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.delivery(MessageInflowLocalProxy.java:268) at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.invoke(MessageInflowLocalProxy.java:138) at $Proxy133.execute(Unknown Source) at org.jboss.resource.adapter.quartz.inflow.QuartzJob.execute(QuartzJob.java:57) at org.quartz.core.JobRunShell.run(JobRunShell.java:203) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520) Caused by: javax.persistence.PersistenceException: org.hibernate.HibernateException: Hibernate Dialect must be explicitly set at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:698) at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:121) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:51) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33) at com.idfbins.nexus.batch.GISDataBatch.init(GISDataBatch.java:42) at com.idfbins.nexus.batch.GISDataBatch.assignLocationsCoordinates(GISDataBatch.java:55) at com.idfbins.nexus.batch.ExecuteGISBatch.execute(ExecuteGISBatch.java:34) 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 org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112) at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166) at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:46) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101) at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126) ... 11 more Caused by: org.hibernate.HibernateException: Hibernate Dialect must be explicitly set at org.hibernate.dialect.DialectFactory.determineDialect(DialectFactory.java:57) at org.hibernate.dialect.DialectFactory.buildDialect(DialectFactory.java:39) at org.hibernate.cfg.SettingsFactory.determineDialect(SettingsFactory.java:409) at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:119) at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:1933) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1216) at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:691) ... 30 more
Here is my setting the the ejb-jar.xml:
<message-driven> <ejb-name>GISBatch</ejb-name> <ejb-class>com.idfbins.nexus.batch.ExecuteGISBatch</ejb-class> <messaging-type>org.quartz.Job</messaging-type> <transaction-type>Container</transaction-type> <activation-config> <activation-config-property> <activation-config-property-name> cronTrigger </activation-config-property-name> <activation-config-property-value> <![CDATA[0 */2 * * * ?]]> </activation-config-property-value> </activation-config-property> </activation-config> </message-driven>
Here is my JBoss.xml:
<?xml version="1.0" encoding="UTF-8"?> <jboss> <enterprise-beans> <message-driven> <ejb-name>QuartzTst2</ejb-name> <resource-adapter-name>quartz-ra.rar</resource-adapter-name> </message-driven> <message-driven> <ejb-name>GISBatch</ejb-name> <resource-adapter-name>quartz-ra.rar</resource-adapter-name> </message-driven> </enterprise-beans> </jboss>
Here is the class that gets scheduled. It is located inside and EAR deployed on JBoss:
package com.idfbins.nexus.batch; import javax.ejb.EJBException; import javax.ejb.MessageDrivenContext; import javax.jms.Message; import org.jboss.logging.Logger; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class ExecuteGISBatch { /** * @param args */ /* public static void main(String[] args) { // TODO Auto-generated method stub GISDataBatch batch = new GISDataBatch(); batch.assignLocationsCoordinates(); } */ private static final Logger log = Logger.getLogger(QuartzTst2.class); public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { log.info("Executing GIS Batch"); log.info("class path="+System.getProperty( "java.class.path" )); GISDataBatch batch = new GISDataBatch(); batch.assignLocationsCoordinates(); } /** * * * * @see javax.ejb.MessageDrivenBean#ejbRemove() * * @throws EJBException */ public void ejbRemove() throws EJBException { } /** * * * * @see javax.ejb.MessageDrivenBean#setMessageDrivenContext(javax.ejb.MessageDrivenContext) * * @param context * * @throws EJBException */ public void setMessageDrivenContext(MessageDrivenContext context) throws EJBException { } /** * * * * @see javax.jms.MessageListener#onMessage(javax.jms.Message) * * @param message */ public void onMessage(Message message) { } public void ejbCreate() { log.info("GIS Batch job created"); } }
I have read that if I set the Quartz property: useClassLoaderOfInitializer to true then it will use the JBoss class loader and everything should be on the classpath. If this is correct, I just need to know where to update or create the quartz.properties file. If I am incorrect I need to find a way to make sure that when the job is run that everything in my EAR is in the classpath. What is the best way to do this?