JBoss Scheduler & Quartz
Par PlaceOweb le dimanche, décembre 4 2011, 11:51 - JAVA - Lien permanent
Scheduler et Quartz avec Jboss, à la recherche d'un service de temps, permettant de paralléliser les processus lancés et à lancer.
Contrairement à ce que dit le post sur Jboss 6.1, il semble possible de paralléliser des processus.
Pour cela déjà 2 solutions sont fonctionnelles :
- Schedulable
- Quartz (et Job)
Schedulable
Dans votre implémentation de "org.jboss.varia.scheduler.Schedulable", il faudra définir la variable "TimerName", pour l'associer sur le timer par défaut, ou bien un autre timer (auto-créé si nouveau) pour que vos différents mbean de temps puissent se chevaucher (êtres lancés en parallèle).
com.placeoweb.schedul.MySchedulable.java
import java.util.Date; import org.jboss.logging.Logger; import org.jboss.varia.scheduler.Schedulable; public class MySchedulable implements Schedulable { private final Logger logger = Logger.getLogger(this.getClass()); public void perform(Date now, long remainingRepetitions) { System.out.println("DEBUT"); logger.debug(this.getClass()+" SCHEDUL DEBUT "+new Date()+" (now:"+now+", remainingRepetitions:"+remainingRepetitions); try { Thread.sleep(5000); } catch (InterruptedException e) { logger.fatal(this.getClass(),e); } logger.debug(this.getClass()+" SCHEDUL FIN "+new Date()); System.out.println("FIN"); } }
META-INF/myscheduler-service.xml
<?xml version="1.0" encoding="UTF-8"?> <server> <!-- java.lang.ClassNotFoundException: org.jboss.mx.timer.JBossTimer from BaseClassLoader --> <!-- http://community.jboss.org/message/571539 --> <!-- <mbean code="org.jboss.mx.timer.JBossTimer" => need to be replaced by "javax.management.timer.Timer" --> <!-- <mbean code="javax.management.timer.Timer" --> <!-- name="jboss:service=Timer2"> --> <!-- </mbean> --> <mbean code="org.jboss.varia.scheduler.Scheduler" name="MySchedulerTest:service=Scheduler"> <attribute name="TimerName">jboss:service=TimerNew</attribute> <!-- Adding this attribute, is binding this scheduled class, on other independent timer service, so you can use parralels calls of yours SchedulableClass. Without using, is default binding on TimerName : jboss:service=Timer --> <attribute name="StartAtStartup">true</attribute> <attribute name="SchedulableClass">com.placeoweb.schedul.MySchedulable</attribute> <attribute name="InitialStartDate">NOW</attribute> <attribute name="SchedulePeriod">1000</attribute> <attribute name="InitialRepetitions">-1</attribute> <attribute name="FixedRate">true</attribute> </mbean> <mbean code="org.jboss.varia.scheduler.Scheduler" name="MySchedulerTest2:service=Scheduler"> <attribute name="StartAtStartup">true</attribute> <attribute name="SchedulableClass">com.placeoweb.schedul.MySchedulable2</attribute> <attribute name="InitialStartDate">NOW</attribute> <attribute name="SchedulePeriod">1000</attribute> <attribute name="InitialRepetitions">-1</attribute> <attribute name="FixedRate">true</attribute> </mbean> </server>
Job et StatefulJob
Dans votre implémentation de "org.quartz.Job", il faudra plutôt implémenter "org.quartz.StatefulJob" pour définir une seule instance de votre mbean, ainsi, si la précédente exécution n'est pas terminée, on attends quelle se termine avant de relancer la suivante.
com.placeoweb.schedul.SimpleQuartzJob.java
import java.util.Date; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.StatefulJob; //public class SimpleQuartzJob implements Job { public class SimpleQuartzJob implements StatefulJob { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("In SimpleQuartzJob - executing its JOB at " + new Date() + " by " + context.getTrigger().getName()); try { System.out.println("Waiting start"); Thread.sleep(12000); System.out.println("Waiting stop"); } catch (InterruptedException e) { e.printStackTrace(); } } }
META-INF/ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 6.0//EN" "http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"> --> <ejb-jar 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/ejb-jar_3_0.xsd"> <enterprise-beans> <message-driven> <ejb-name>ExampleMDB</ejb-name> <!-- < ! - - <ejb-class>org.jboss.tutorial.quartz.bean.QuartzMDBBean</ejb-class> - - > --> <ejb-class>com.placeoweb.schedul.SimpleQuartzJob</ejb-class> <transaction-type>Container</transaction-type> <activation-config> <activation-config-property> <activation-config-property-name>cronTrigger</activation-config-property-name> <activation-config-property-value>0/2 * * * * ?</activation-config-property-value> </activation-config-property> </activation-config> </message-driven> <message-driven> <ejb-name>ExampleMDB2</ejb-name> <!-- < ! - - <ejb-class>org.jboss.tutorial.quartz.bean.QuartzMDBBean</ejb-class> - - > --> <ejb-class>com.placeoweb.SimpleQuartzJob2</ejb-class> <transaction-type>Container</transaction-type> <activation-config> <activation-config-property> <activation-config-property-name>cronTrigger</activation-config-property-name> <activation-config-property-value>0/2 * * * * ?</activation-config-property-value> </activation-config-property> </activation-config> </message-driven> </enterprise-beans> </ejb-jar>
META-INF\jboss.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 6.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_6_0.dtd"> <jboss> <enterprise-beans> <message-driven> <ejb-name>ExampleMDB</ejb-name> <resource-adapter-name>quartz-ra.rar</resource-adapter-name> </message-driven> <message-driven> <ejb-name>ExampleMDB2</ejb-name> <resource-adapter-name>quartz-ra.rar</resource-adapter-name> </message-driven> </enterprise-beans> </jboss>
Other way, with attributes names (without any file deployer like META-INF/ejb-jar.xml and META-INF\jboss.xml)
import javax.ejb.ActivationConfigProperty; import javax.ejb.MessageDriven; import org.jboss.ejb3.annotation.ResourceAdapter; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; // http://docs.jboss.org/ejb3/docs/tutorial/1.0.7/html/Quartz_scheduler_integration.html // NOTE : Currently only cron jobs are allowed to be configured. @MessageDriven(activationConfig = {@ActivationConfigProperty(propertyName = "cronTrigger", propertyValue = "*/10 * * * * ?")}) // OK, génère une Java Class : org.jboss.ejb3.mdb.MessagingDelegateWrapper Description : Management Bean. @ResourceAdapter("quartz-ra.rar") public class TestQuartzJboss implements Job { @Override public void execute(JobExecutionContext arg0) throws JobExecutionException { System.out.println("HEllo de lu fron Quartz"); } }
Ressources
Jboss 6.1
boot.log d'un Jboss 6.1 et la section relative au lancement du service Quartz :
15:59:57,086 INFO [AbstractServer] Starting: JBossAS [6.1.0.Final "Neo"] 16:00:28,086 INFO [RARDeployment] Required license terms exist, view vfs:/C:/jboss-6.1.0.Final/server/default/deploy/quartz-ra.rar/META-INF/ra.xml 16:00:28,226 INFO [SimpleThreadPool] Job execution threads will use class loader of thread: Thread-2 16:00:28,273 INFO [SchedulerSignalerImpl] Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl 16:00:28,273 INFO [QuartzScheduler] Quartz Scheduler v.1.8.3 created. 16:00:28,273 INFO [RAMJobStore] RAMJobStore initialized. 16:00:28,273 INFO [QuartzScheduler] Scheduler meta-data: Quartz Scheduler (v1.8.3) 'JBossQuartzScheduler' 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. 16:00:28,273 INFO [StdSchedulerFactory] Quartz scheduler 'JBossQuartzScheduler' initialized from an externally opened InputStream. 16:00:28,273 INFO [StdSchedulerFactory] Quartz scheduler version: 1.8.3 16:00:28,273 INFO [QuartzScheduler] Scheduler JBossQuartzScheduler_$_NON_CLUSTERED started.
mastertheboss.com - Application Server
- Quartz advanced tutorial (JBoss AS 6 which ships with Quartz 1.8.3 release)
- JBoss Quartz tutorial
Job scheduling with Quartz
Jobs and triggers
The two fundamental units of Quartz's scheduling package are jobs and triggers. A job is an executable task that can be scheduled, while a trigger provides a schedule for a job. While these two entities could easily have been combined, their separation in Quartz is both intentional and beneficial.
Les deux unités fondamentales du paquet d'ordonnancement de Quartz sont des emplois (jobs) et des déclencheurs (triggers). Un emploi est une tâche exécutable qui peut être prévue, alors qu'un déclencheur fournit un calendrier pour un emploi. Bien que ces deux entités auraient pu être facilement combinés, leur séparation en quartz est à la fois intentionnelle et bénéfique.
- Exemple 1: Jobs
- Exemple 2: Simple triggers
- Exemple 3: Cron triggers
- Job stores ( JDBCJobStore à la place du défaut RAMJobStore )
Using Quartz Scheduler in a Java web app (servlet)
You'll notice that i'm implementing StatefulJob instead of plain Job - this is so that if the job is still running when it is due to start again, Quartz won't start another instance of it:
//public class SimpleQuartzJob implements Job { public class SimpleQuartzJob implements StatefulJob { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("In SimpleQuartzJob - executing its JOB at " + new Date() + " by " + context.getTrigger().getName()); try { System.out.println("Waiting start"); Thread.sleep(12000); System.out.println("Waiting stop"); } catch (InterruptedException e) { e.printStackTrace(); } } }
Autre
- Chapter 17. Quartz scheduler integration
- Chapter 13. Scheduler
- Chapter 10. Additional Services 10.4. Scheduling Tasks
- org.jboss.varia.scheduler Interface SchedulerMBean
- Quartz scheduler example
- More About Simple Trigger
- Official Quartz.NET Tutorial Quartz.NET is a pure .NET library written in C# and is a port of very propular open source Java job scheduling framework, Quartz.
Fichiers inclus avec JBoss 6.1
C:\jboss-6.1.0.Final\server\default\deploy\quartz-ra.rar\quartz-ra.jar\org\jboss\resource\adapter\quartz\inflow\quartz.properties
# Quartz configuration properties org.quartz.scheduler.instanceName = JBossQuartzScheduler org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 10 org.quartz.threadPool.threadPriority = 5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true # Don't check for new versions of quartz org.quartz.scheduler.skipUpdateCheck = true
C:\jboss-6.1.0.Final\server\default\deploy\quartz-ra.rar\META-INF\ra.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- $Id: ra.xml 71556 2008-04-01 13:39:35Z adrian@jboss.org $ --> <connector xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd" version="1.5"> <description>Quartz Inflow Resource Adapter</description> <display-name>Quartz Adapter</display-name> <vendor-name>Red Hat Middleware LLC</vendor-name> <eis-type>Quartz Adapter</eis-type> <resourceadapter-version>5.0</resourceadapter-version> <license> <description> JBoss, Home of Professional Open Source. Copyright 2006, Red Hat Middleware LLC, and individual contributors as indicated by the @author tags. See the copyright.txt file in the distribution for a full listing of individual contributors. This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this software; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF site: http://www.fsf.org. </description> <license-required>true</license-required> </license> <resourceadapter> <resourceadapter-class>org.jboss.resource.adapter.quartz.inflow.QuartzResourceAdapter</resourceadapter-class> <inbound-resourceadapter> <messageadapter> <messagelistener> <messagelistener-type>org.quartz.Job</messagelistener-type> <activationspec> <activationspec-class>org.jboss.resource.adapter.quartz.inflow.QuartzActivationSpec</activationspec-class> <required-config-property> <config-property-name>cronTrigger</config-property-name> </required-config-property> </activationspec> </messagelistener> <messagelistener> <messagelistener-type>org.quartz.StatefulJob</messagelistener-type> <activationspec> <activationspec-class>org.jboss.resource.adapter.quartz.inflow.QuartzActivationSpec</activationspec-class> <required-config-property> <config-property-name>cronTrigger</config-property-name> </required-config-property> </activationspec> </messagelistener> </messageadapter> </inbound-resourceadapter> </resourceadapter> </connector>