10 Replies Latest reply: Apr 11, 2012 8:24 AM by nathan dennis RSS

using quartz directly

gebuh Newbie

I'm using Quartz with the JobStoreCMT configuration and several jobs that need to be run.  I started out using QuartzTriggerHandle, but couldn't make it work with multiple jobs and the Quartz database configuration.  So I implemented the Quartz Job class in my processors and created my own scheduler.  I'm sure this is a bad thing, my jobs work, but I've lost any transaction management I had before.   So, what I'm doing (don't judge me):

My scheduler:

@Observer("org.jboss.seam.postInitialization")
    public void scheduleTimer() {
        log.info("starting quartz timer");
        this.createAndStartScheduler();

        // here's where you add your job - BaseProcessor implements quartz.Job, my classes extend BaseProcessor
        this.loadQuartzJobs();
        //schedule them all
        if(this.jobsToRun != null){
            for(BaseProcessor each : this.jobsToRun){
                JobDetail job = new JobDetail(each.getJobname(), each.getGroupname(), each.getClass());
                CronTrigger trig = each.getCronTrigger();
                log.info("scheduling " + job.getName() + " trigger: " + trig.getCronExpression());
                try {
                    this.scheduler.addJob(job, true);
                    this.scheduler.scheduleJob(trig);
                } catch (SchedulerException e) {
                    log.error("could not schedule job: " + e);
                }
            }
        }

 

my job execute method:

public void execute(JobExecutionContext context)throws JobExecutionException {
        log.debug("last fire time: " + context.getPreviousFireTime());
        Lifecycle.beginCall();
        //TODO for some reason, lost seam context, add it here
        this.someTemplateIneed = (EmailNotificationTemplate)Component.getInstance("someTemplateIneed");
        this.renderer = (Renderer) Component.getInstance(Renderer.class);
        this.sendEmails();
        Lifecycle.endCall();
        log.debug("next fire time: " + context.getNextFireTime());
    }

I also have to do a database insert at the end of each job (I said don't judge me):

private void logEmailHistoryToDatabase(EmailRecipientsV each) {
        try {
           // create an object to insert ....
            if(object != null){
                UserTransaction userTx = (UserTransaction)Component.getInstance("org.jboss.seam.transaction.transaction");
                userTx.setTransactionTimeout(10 * 60); 
                userTx.begin();


                EntityManager entitymanager = (EntityManager)Component.getInstance("entityManager");
                entitymanager.joinTransaction();
                entitymanager.persist(object);
                entitymanager.flush();
                userTx.commit();
            }
        } catch (Exception e) {
            log.error("error saving to email history: " + e);
        }
    }

Is there a better way to do this?

 

 

I also found something in org.jboss.seam.async.QuartzDispatcher.initScheduler, shouldn't this InputStream be closed?      

public void initScheduler() throws SchedulerException
   {
       StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();

       //TODO: magical properties files are *not* the way to config Seam apps!
       InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("seam.quartz.properties");  //<-----------
       if (is != null)
       {
         schedulerFactory.initialize(is);
         log.debug("Found seam.quartz.properties file. Using it for Quartz config.");
       } 
       else 
       {
         schedulerFactory.initialize();
         log.warn("No seam.quartz.properties file. Using in-memory job store.");
       }

       scheduler = schedulerFactory.getScheduler();
       scheduler.start();
   }
  • 1. Re: using quartz directly
    nathan dennis Expert

    i think you gave up a little to easy on the QuartzTriggerHandle. I use it all the time and store the jobs in the database using JobStoreCMT w/ handles so that the jobs can be paused, resumed cancelled ,,,etc.

     

    if you want help using the seam's components.. i would be happy to help and give examples.. otherwise im guessing the quartz forum is the place for a quartz discussion.

     

    let me know if you want to give QuartzTriggerHandles another shot.

     

    best of luck

  • 2. Re: using quartz directly
    gebuh Newbie

    nathan dennis wrote:

     

    i think you gave up a little to easy on the QuartzTriggerHandle. I use it all the time and store the jobs in the database using JobStoreCMT w/ handles so that the jobs can be paused, resumed cancelled ,,,etc.

     

    if you want help using the seam's components.. i would be happy to help and give examples.. otherwise im guessing the quartz forum is the place for a quartz discussion.

     

    let me know if you want to give QuartzTriggerHandles another shot.

     

    best of luck

    Thanx Nathan, I'd appreciate it.  It's entirely possible I gave up too soon.

  • 3. Re: using quartz directly
    nathan dennis Expert

    seam.quartz.properties -- has to be in the jar  directory if using exploded ear files.. so add it to the build.xml

     

    org.quartz.scheduler.instanceName = schedule

    org.quartz.scheduler.instanceId = 1

    org.quartz.scheduler.rmi.export = false

    org.quartz.scheduler.rmi.proxy = false

    org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer = true

     

    org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

    org.quartz.threadPool.threadCount = 3

    org.quartz.logger.schedLogger.class = org.quartz.impl.Log4jLogger

     

    org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreCMT

     

     

    org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate

    org.quartz.jobStore.dataSource = quartzDatasource

    org.quartz.jobStore.nonManagedTXDataSource = noTxquartzDatasource

    org.quartz.jobStore.tablePrefix = qrtz_

     

    org.quartz.dataSource.quartzDatasource.jndiURL=java:/quartzDatasource

    org.quartz.dataSource.noTxquartzDatasource.jndiURL=java:/noTxquartzDatasource

     

    going to need some data sources... i actually split up the quartz job database from the database i uses to store the handles and other application stuff.

     

     

     

    quartzDS.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE datasources

        PUBLIC "-//JBoss//DTD JBOSS JCA Config 1.5//EN"

        "http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd">

    <datasources>

       <xa-datasource>

          <jndi-name>quartzDatasource</jndi-name>

          <track-connection-by-tx/>

          <xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>

          <xa-datasource-property name="ServerName">localhost</xa-datasource-property>  

          <xa-datasource-property name="PortNumber">5432</xa-datasource-property>

          <xa-datasource-property name="DatabaseName">quartz</xa-datasource-property>    

          <xa-datasource-property name="User">sa</xa-datasource-property>

          <xa-datasource-property name="Password">sa</xa-datasource-property>    

     

       </xa-datasource>

     

       <no-tx-datasource>

          <jndi-name>noTxquartzDatasource</jndi-name>

                    <connection-url>jdbc:postgresql://localhost/quartz</connection-url>

                    <driver-class>org.postgresql.Driver</driver-class>

                    <user-name>sa</user-name>

                    <password>sa</password>

     

       </no-tx-datasource>   

    </datasources>

     

    second datasource

    handleDS.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE datasources

        PUBLIC "-//JBoss//DTD JBOSS JCA Config 1.5//EN"

        "http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd">

    <datasources>

     

       <xa-datasource>

          <jndi-name>quartzHandleDatasource</jndi-name>

          <track-connection-by-tx/>

          <xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>

          <xa-datasource-property name="ServerName">localhost</xa-datasource-property>  

          <xa-datasource-property name="PortNumber">5432</xa-datasource-property>

          <xa-datasource-property name="DatabaseName">handlequartz</xa-datasource-property>    

          <xa-datasource-property name="User">sa</xa-datasource-property>

          <xa-datasource-property name="Password">sa</xa-datasource-property>    

     

       </xa-datasource>

     

       <no-tx-datasource>

          <jndi-name>noTxquartzHandleDatasource</jndi-name>

                    <connection-url>jdbc:postgresql://localhost/handlequartz</connection-url>

                    <driver-class>org.postgresql.Driver</driver-class>

                    <user-name>sa</user-name>

                    <password>sa</password>

     

       </no-tx-datasource>   

    </datasources>

     

     

     

     

    ---- persistence.xml

     

     

     

    <persistence-unit name="handleQuartzStorePU" transaction-type="JTA">

        <provider>org.hibernate.ejb.HibernatePersistence</provider>

            <jta-data-source>java:/quartzHandleDatasource</jta-data-source>

            <class>org.monarchnc.aulm.model.quartz.QuartzHandles</class>

            <exclude-unlisted-classes >true</exclude-unlisted-classes>

        <properties>

            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>       

            <property name="hibernate.hbm2ddl.auto" value="update"/>

            <property name="hibernate.show_sql" value="true"/>

            <property name="hibernate.format_sql" value="true"/>

            <property name="jboss.entity.manager.factory.jndi.name" value="java:/quartzemf"/>

        </properties>

    </persistence-unit>

     

     

    ------components.xml

     

    <persistence:managed-persistence-context name="quartzEntityManager" auto-create="true"

    persistence-unit-jndi-name="java:/quartzemf"/>

    <async:quartz-dispatcher/>

     

     

     

     

     

    make sure you add quartz.jar to your deployed-jars.ear.list

    next an entity to store the handles

     

     

     

     

    @Entity

    @Table(name = "quartz_handles")

    public class QuartzHandles implements Serializable {

     

     

        /**

         * @author Nathan Dennis

         */

        private static final long serialVersionUID = -9080580543695591916L;

     

        private long id;

        private QuartzTriggerHandle quartzTriggerHandle;

        private Date timestamp;

        private Date startdate =Calendar.getInstance().getTime();

     

        private Date enddate=Calendar.getInstance().getTime();

        private String cron = "0 /5 * * * ?";

        private String handleName;

        private String methodName;

        private boolean active = true;

     

     

     

        @Id @GeneratedValue

        @Column(name = "id")

        public long getId() {

            return this.id;

        }

     

        public void setId(long id) {

            this.id = id;

        }

     

     

        @Column(name = "handle_name", nullable = false, length = 250)

        @Length(max = 250)

        @NotNull

        public String getHandleName() {

            return this.handleName;

        }

     

        public void setHandleName(String handleName){

            this.handleName=handleName;

        }

     

        @Column(name = "method_name", nullable = false, length = 250)

        @Length(max = 250)

        @NotNull

        public String getMethodName() {

            return this.methodName;

        }

     

        public void setMethodName(String methodName){

            this.methodName=methodName;

        }

     

        @Temporal(TemporalType.TIMESTAMP)

        @Column(name = "timestamp", length = 8)

        public Date getTimestamp() {

            return this.timestamp;

        }

     

        public void setTimestamp(Date timestamp) {

            this.timestamp = timestamp;

        }

     

     

     

        @Column(name = "handle")

        public QuartzTriggerHandle getQuartzTriggerHandle() {

            return quartzTriggerHandle;

        }

        public void setQuartzTriggerHandle(QuartzTriggerHandle quartzTriggerHandle) {

            this.quartzTriggerHandle = quartzTriggerHandle;

        }

     

        @Temporal(TemporalType.TIMESTAMP)

        @Column(name="startdate")

        public Date getStartdate() {

            return startdate;

        }

     

        public void setStartdate(Date startdate) {

            this.startdate = startdate;

        }

     

        @Column(name = "cron", length=250,  nullable = false)

        @Length(max = 250)

        public String getCron() {

            return cron;

        }

     

        public void setCron(String cron) {

            this.cron = cron;

        }

        @Temporal(TemporalType.TIMESTAMP)

        @Column(name="enddate")

        public Date getEnddate() {

            return enddate;

        }

     

        public void setEnddate(Date enddate) {

            this.enddate = enddate;

        }

     

        @Column(name="active")

        public boolean isActive() {

            return active;

        }

     

        public void setActive(boolean active) {

            this.active = active;

        }

     

     

    }

     

     

     

     

     

    home and list objects.. PAY ATTENTION TO THE PERSISTENCE I OVERRIDE

     

     

     

    @Name("quartzHandlesHome")

    public class QuartzHandlesHome extends EntityHome<QuartzHandles>

    {

        /**

         * @author Nathan Dennis

         * home object for  cron

         */

        private static final long serialVersionUID = 9193388548689584255L;

     

        @Logger Log log;

        public void setQuartzHandlesId(Long id) {

            setId(id);

        }

     

        public Long getQuartzHandlesId() {

            return (Long) getId();

        }

     

     

        @Override

        protected QuartzHandles createInstance() {

            QuartzHandles quartzHandles = new QuartzHandles();

            return quartzHandles;

        }

     

        public void load() {

            if (isIdDefined()) {

                wire();

            }

        }

     

        public void wire() {

            getInstance();

        }

     

        public boolean isWired() {

            return true;

        }

     

        public QuartzHandles getDefinedInstance() {

            return isIdDefined() ? getInstance() : null;

        }

     

       @Override

       protected String getPersistenceContextName() {

            return "quartzEntityManager";

       }

     

     

    }

     

     

    -------------------

    List object

    -------------------

     

    import org.jboss.seam.annotations.Name;

    import org.jboss.seam.framework.EntityQuery;

     

     

    import java.util.Arrays;

     

    @Name("quartzHandlesList")

    public class QuartzHandlesList extends EntityQuery<QuartzHandles> {

     

        /**

         * @author Nathan Dennis

         *  cron manager list bean

         */

        private static final long serialVersionUID = 6814491664526846768L;

     

        private static final String EJBQL = "select quartzHandles from QuartzHandles quartzHandles";

     

        private static final String[] RESTRICTIONS = {

                "lower(quartzHandles.cron) like lower(concat(#{quartzHandlesList.quartzHandles.cron},'%'))",

                "lower(quartzHandles.handleName) like lower(concat(#{quartzHandlesList.quartzHandles.handleName},'%'))",

                "lower(quartzHandles.methodName) like lower(concat(#{quartzHandlesList.quartzHandles.methodName},'%'))",};

     

        private QuartzHandles quartzHandles = new QuartzHandles();

     

        public QuartzHandlesList() {

            setEjbql(EJBQL);

            setRestrictionExpressionStrings(Arrays.asList(RESTRICTIONS));

            setMaxResults(25);

        }

     

        public QuartzHandles getQuartzHandles() {

            return quartzHandles;

        }

     

           @Override

           protected String getPersistenceContextName() {

                return "quartzEntityManager";

           }

    }

     

     

     

    here is where it started getting shaky. i had a little trouble getting the vailidator to work.. so i moved some of this mess into another bean...
    just conversation issues.. and i got tired of fighting it.... dont laugh.. it was a cheap shot and it works. lol 

     

    @Stateful

    @Name("quartzEditAction")

    @Scope(ScopeType.CONVERSATION)

    public class QuartzEditAction implements QuartzEditLocal{

        /**

         * @author nathan dennis

         * @unit

         * @date

         */

     

        @In(required=true)

        EntityHome<QuartzHandles> quartzHandlesHome;

        @In AsyncGenericProcessor asyncGenericProcessor;

        @In

        EntityManager quartzEntityManager;

     

        private String handleName;

        private String methodName;

        private String cron = "0 /5 * * * ?";

        private Date startdate = Calendar.getInstance().getTime();

        private Date enddate = Calendar.getInstance().getTime();

     

     

        public void init(){

            if(quartzHandlesHome.isManaged()){

                this.handleName = quartzHandlesHome.getInstance().getHandleName();

                this.methodName = quartzHandlesHome.getInstance().getMethodName();

                this.cron = quartzHandlesHome.getInstance().getCron();

                this.startdate = quartzHandlesHome.getInstance().getStartdate();

                this.enddate = quartzHandlesHome.getInstance().getEnddate();

            }

     

        }

     

        private void copy(){

            quartzHandlesHome.getInstance().setHandleName(handleName);

            quartzHandlesHome.getInstance().setMethodName(methodName);

            quartzHandlesHome.getInstance().setStartdate(startdate);

            quartzHandlesHome.getInstance().setEnddate(enddate);

            quartzHandlesHome.getInstance().setCron(cron);

        }

     

        public String save(){

            String result = "failed";

            copy();

            if (quartzHandlesHome.isManaged()){

                result = quartzHandlesHome.update();

            } else {

                result = quartzHandlesHome.persist();

            }

            return result;

        }

     

        public String remove(){

            String result = "failed";

            QuartzTriggerHandle handle = quartzHandlesHome.getInstance().getQuartzTriggerHandle();

            quartzHandlesHome.getInstance().setQuartzTriggerHandle(null);

            //quartzHandlesHome.getInstance().setActive(false);

     

            try

            {

                handle.cancel();

                result = "deleted";

            }

            catch (Exception nsole)

            {

                FacesMessages.instance().add("Delete Failed");

     

            }

            result = quartzHandlesHome.remove();

            return result;

        }

     

     

     

        public void methodValidator(FacesContext context,

                UIComponent toValidate, Object value) throws ValidatorException {

     

     

            String method = (String) value.toString();  

     

            System.out.print("context handlename: " + handleName);

     

     

                   if(handleName == null || handleName.isEmpty()){

     

                     throw new ValidatorException(new FacesMessage("Class (handleName) can't be null. Please set it to the EJB name for the class you wish to execute from."));

                   } else if (method == null || method.isEmpty()){

                     throw new ValidatorException(new FacesMessage("Method name can't be null. Please enter the method name from handle seleted including only the alpha characters."));   

                   } else {

                       GenericLocal test = (GenericLocal) Component.getInstance("genericProcessing");

                       boolean sw = test.methodExist(Component.getInstance(handleName), method);

     

                       if(sw){

                        //do nothing

                           System.out.println("METHOD EXIST");

                    } else {

                        System.out.println("METHOD CANT BE FOUND");

                        FacesMessage message = new FacesMessage();

                        message.setDetail("Method "+ method +" does not exist in class: " + handleName);

                        message.setSummary("Method "+ method +" does not exist in class: " + handleName);

                        message.setSeverity(FacesMessage.SEVERITY_ERROR);

                        throw new ValidatorException(message);

                    }

     

              }

     

     

        }

     

        public void classValidator(FacesContext context,

                UIComponent toValidate, Object value) throws ValidatorException {

     

            String handleName = (String) value.toString();

            if(handleName == null || handleName.isEmpty()){

                    throw new ValidatorException(new FacesMessage("Class (handleName) can't be null. Please set it to the EJB name for the class you wish to execute from."));

            } else {

                //rediculous hack...

                this.handleName = handleName;

                GenericLocal test = (GenericLocal) Component.getInstance("genericProcessing");

                    boolean sw = test.classExist(Component.getInstance(handleName));

     

                    if(sw){

                    //do nothing

                      //  System.out.println("METHOD EXIST");

                } else {

                    System.out.println("CLASS CANT BE FOUND");

                    FacesMessage message = new FacesMessage();

                    message.setDetail("Class "+ handleName +" does not exist");

                    message.setSummary("Class "+ handleName +" does not exist");

                    message.setSeverity(FacesMessage.SEVERITY_ERROR);

                    throw new ValidatorException(message);

                }

     

     

              }

     

     

        }

     

     

        public String create()

        {

            String result = save();

            QuartzHandles quartzHandles = quartzHandlesHome.getInstance();

            QuartzTriggerHandle handle;

            try {

                handle = asyncGenericProcessor.scheduleQue(quartzHandles.getStartdate(),

                                                        quartzHandles.getCron(),

                                                        quartzHandles.getEnddate(),

                                                        quartzHandles);

            quartzHandles.setQuartzTriggerHandle( handle );

           // this.quartzEntityManager.merge(quartzHandles);

            this.quartzHandlesHome.getInstance().setQuartzTriggerHandle(handle);

            quartzHandlesHome.update();

     

     

            System.out.println(quartzHandles.getQuartzTriggerHandle().toString());

            } catch (IOException e) {

                FacesMessages.instance().add("Create Cron Failed.");

                e.printStackTrace();

                result = "failed";

            }

     

            return result;

        }

     

     

        @Transactional

        public String cancel() {

            String result = "updated";

            QuartzHandles quartzHandles = quartzHandlesHome.getInstance();

     

            QuartzTriggerHandle handle = quartzHandles.getQuartzTriggerHandle();

            quartzHandles.setQuartzTriggerHandle(null);

            quartzHandles.setActive(false);

     

            try

            {

                handle.cancel();

            }

            catch (Exception nsole)

            {

                result="failed";

                FacesMessages.instance().add("Cancel Cron Failed.");

            }

            return result;

        }

     

     

        @Transactional

        public String pause(){

            String result = "updated";

            QuartzHandles quartzHandles = quartzHandlesHome.getInstance();

            try {

                    quartzHandles.getQuartzTriggerHandle().pause();

                    FacesMessages.instance().add("Cron Paused.");

     

            } catch (Exception e) {

                result = "failed";

                e.printStackTrace();

                FacesMessages.instance().add("Pause Cron Failed.");

            }

            return result;

     

        }

        @Transactional

        public String resume(){

            String result = "updated";

            QuartzHandles quartzHandles = quartzHandlesHome.getInstance();

     

            try {

                    quartzHandles.getQuartzTriggerHandle().resume();

                    FacesMessages.instance().add("Cron Resumed.");

            } catch (Exception e) {

                result = "failed";

                e.printStackTrace();

                FacesMessages.instance().add("Pause Cron Failed.");

            }

            return result;

     

        }

     

     

     

        public String getHandleName() {

            return handleName;

        }

     

        public void setHandleName(String handleName) {

            this.handleName = handleName;

        }

     

        public String getMethodName() {

            return methodName;

        }

     

        public void setMethodName(String methodName) {

            this.methodName = methodName;

        }

     

        public String getCron() {

            return cron;

        }

     

        public void setCron(String cron) {

            this.cron = cron;

        }

     

        public Date getStartdate() {

            return startdate;

        }

     

        public void setStartdate(Date startdate) {

            this.startdate = startdate;

        }

     

        public Date getEnddate() {

            return enddate;

        }

     

        public void setEnddate(Date enddate) {

            this.enddate = enddate;

        }

     

        @Destroy @Remove

        public void destroy() {}

     

    }

     

     

     

    now we need the Asynchronous bean... tricky here.. i didnt see it documented anywhere...
    looks like it is returning null,, but it is actually returning the handle. seam magic happens.
    i would have like to have seen a little more said about this. but here it is.

     

     

     

    @Name("asyncGenericProcessor") 

    @AutoCreate

    public class AsyncGenericProcessor {

     

     

        @Logger Log log;

     

       // @In

      // EntityManager quartzEntityManager;

     

     

        @Asynchronous

        @Transactional

        public QuartzTriggerHandle scheduleQue(@Expiration Date when,

                                                     @IntervalCron String cron,

                                                     @FinalExpiration Date endDate,

                                                     QuartzHandles quartzHandles) throws IOException

        {

            //quartzHandles = quartzEntityManager.merge(quartzHandles); //this will overwrite the original handle after the initial firing of the job.. dont know why they had it in the example. doesnt work well.

     

            GenericLocal np = (GenericLocal) Component.getInstance("genericProcessing");

            np.getProperty(Component.getInstance(quartzHandles.getHandleName()), quartzHandles.getMethodName());

     

            return null;

        }

    }

     

    ---------interface

    @Local

    public interface GenericAsyncLocal {

        /**

         * @author nathan dennis

         * @unit

         * @date

         */

        public QuartzTriggerHandle scheduleQue(@Expiration Date when,

                 @IntervalCron String cron,

                 @FinalExpiration Date endDate,

                 long id) throws IOException;

     

     

    }

     

     

    i guess this could be considered mental masterbation at this point, but i though it was pretty awesome idea even if i did come up with it myself. =)

    be sure to restrict access to it using drools or something if it isnt interaweb sort of app

    i didnt clean up the code either... there are some unused objects in here

     

    @Name("genericProcessing")

    @Stateless

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

    @TransactionTimeout(600)

    public class GenericProcessing<T> implements GenericLocal{

        /**

         * @author nathan dennis

         * @unit

         * @date

         */

     

        @SuppressWarnings({ "rawtypes", "unchecked" })

        public <T> T getProperty(Object bean, String propertyName)

        {

          //  System.out.print("inside generic");

            if (bean == null ||

                propertyName == null ||

                propertyName.length() == 0)

            {

                return null;

            }

            // --- Based on the property name build the getter method name ---

     

            String methodName=propertyName;

            T property = null;

            try

            {

                java.lang.Class c = bean.getClass();

                java.lang.reflect.Method m = c.getMethod(methodName, null);

                property = (T) m.invoke(bean, null);

            }

            catch (Exception e)

            {

                e.printStackTrace();

            }

            return property;

        }

        @SuppressWarnings({ "rawtypes", "unchecked" })

        public boolean classExist(Object bean)

        {

     

           // System.out.print("inside generic");

            if (bean == null)

            {

                return false;

            }

            // --- Based on the property name build the getter method name --

            try

            {

                java.lang.Class c = bean.getClass();

                return true;

            }catch (Exception e) {

     

                e.printStackTrace();

                return false;

            }

        }

     

     

        @SuppressWarnings({ "rawtypes", "unchecked" })

        public boolean methodExist(Object bean, String propertyName)

        {

            boolean sw = false;

           // System.out.print("inside generic method test");

            if (bean == null ||

                propertyName == null ||

                propertyName.length() == 0)

            {

                return false;

            }

            // --- Based on the property name build the getter method name ---

            String methodName=propertyName;

            T property = null;

            try

            {

                java.lang.Class c = bean.getClass();

                //java.lang.reflect.Method m = c.getMethod(methodName, null);

                Method m[] = c.getDeclaredMethods();

     

                for (int i = 0; i < m.length; i++){

                    System.out.println(m[i].toString());

                    if(m[i].getName().equals(methodName)){

                        sw = true;

                    }

     

                }

           }

            catch (Exception e)

            {

                e.printStackTrace();

                // --- Handle exception --

            }

            return sw;

        }

     

     

    }

     

     

    and a jsf page something like this to enter in the jobs.. X)

    i am using the normal seam-gen structure for listing and reviewing.. 

    <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"

        xmlns:s="http://jboss.com/products/seam/taglib"

        xmlns:ui="http://java.sun.com/jsf/facelets"

        xmlns:f="http://java.sun.com/jsf/core"

        xmlns:h="http://java.sun.com/jsf/html"

        xmlns:a="http://richfaces.org/a4j"

        xmlns:rich="http://richfaces.org/rich"

        template="../layout/template.xhtml">

     

    <ui:define name="body">

     

        <h:form id="quartzHandles" styleClass="edit">

     

            <rich:panel>

                <f:facet name="header">#{quartzHandlesHome.managed ? 'Edit' : 'Add'} Quartz handles</f:facet>

     

     

                <s:decorate id="idField" template="../layout/edit.xhtml">

                    <ui:define name="label">Id</ui:define>

                    <h:inputText id="id"

                           required="true"

                           disabled="true"

                              value="#{quartzHandlesHome.instance.id}">

                        <a:support event="onblur" reRender="idField" bypassUpdates="true" ajaxSingle="true"/>

                    </h:inputText>

                </s:decorate>

     

     

                <s:decorate id="cronField" template="../layout/edit.xhtml">

                    <ui:define name="label">Cron</ui:define>

                    <h:inputText id="cron"

                                  required="true"

                                  value="#{quartzEditAction.cron}">

                       <a:support event="onblur" reRender="cronField" bypassUpdates="true" ajaxSingle="true"/>

                    </h:inputText>

                </s:decorate>

     

                <s:decorate id="startdateField" template="../layout/edit.xhtml">

                    <ui:define name="label">Startdate</ui:define>

                    <rich:calendar id="startdate"

                              value="#{quartzEditAction.startdate}" datePattern="MM/dd/yyyy hh:mm a"/>

                </s:decorate>

     

     

                <s:decorate id="enddateField" template="../layout/edit.xhtml">

                    <ui:define name="label">Enddate</ui:define>

                    <rich:calendar id="enddate"

                              value="#{quartzEditAction.enddate}" datePattern="MM/dd/yyyy hh:mm a"/>

                </s:decorate>

     

     

     

     

     

                <s:decorate id="handleNameField" template="../layout/edit.xhtml">

                    <ui:define name="label">Handle name</ui:define>

                    <h:inputText id="handleName" validator="#{quartzEditAction.classValidator}"    

                               required="true"

                                  value="#{quartzEditAction.handleName}">

                              <a:support event="onblur" reRender="handleNameField" bypassUpdates="true" ajaxSingle="true">

     

                              </a:support>

                    </h:inputText>        

                </s:decorate>     

     

                <s:decorate id="methodNameField" template="../layout/edit.xhtml">

                    <ui:define name="label">Method Name</ui:define>

                    <h:inputText id="methodName" validator="#{quartzEditAction.methodValidator}"

                               required="true"    

                                  value="#{quartzEditAction.methodName}">

                              <a:support event="onblur" reRender="methodNameField" bypassUpdates="true" ajaxSingle="true">

     

                                </a:support>      

                    </h:inputText>                    

                </s:decorate>      

     

     

     

                <div style="clear:both"> 

                    <span class="required">*</span>                  

                    required fields 

                </div>

     

            </rich:panel>

     

            <div class="actionButtons">

     

                <h:commandButton id="save"

                              value="Create"

                             action="#{quartzEditAction.create}"

                           disabled="#{!quartzHandlesHome.wired}"

                           rendered="#{!quartzHandlesHome.managed}"/>

     

                <h:commandButton id="update"   

                              value="Save"

                             action="#{quartzEditAction.save}"

                           rendered="#{quartzHandlesHome.managed}"/>

     

     

                <h:commandButton id="pause"

                              value="Pause"

                             action="#{quartzEditAction.pause}"

                           rendered="#{quartzHandlesHome.managed}"/>                      

     

                <h:commandButton id="resume"

                              value="Resume"

                             action="#{quartzEditAction.resume()}"

                           rendered="#{quartzHandlesHome.managed}"/>                      

     

     

                <h:commandButton id="delete"

                              value="Delete"

                             action="#{quartzEditAction.remove}"

                          immediate="true"

                           rendered="#{quartzHandlesHome.managed}"/>

     

                <s:button id="cancelEdit"

                       value="Go Back (Cancel)"

                 propagation="end"

                        view="/quartz/QuartzHandles.xhtml"

                    rendered="#{quartzHandlesHome.managed}"/>

     

                <s:button id="cancelAdd"

                       value="Cancel"

                 propagation="end"

                        view="/quartz/#{empty quartzHandlesFrom ? 'QuartzHandlesList' : quartzHandlesFrom}.xhtml"

                    rendered="#{!quartzHandlesHome.managed}"/>

     

            </div>

        </h:form>

     

    </ui:define>

     

    </ui:composition>

     

     

     

    ---pages.xml

     

     

    <?xml version="1.0" encoding="UTF-8"?>

    <page xmlns="http://jboss.com/products/seam/pages"

          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"

          no-conversation-view-id="/quartz/QuartzHandlesList.xhtml"

           login-required="true">

     

       <begin-conversation join="true" flush-mode="MANUAL"/>

     

       <action execute="#{quartzHandlesHome.wire}"/>

        <action execute="#{quartzEditAction.init()}"/>

     

       <param name="quartzHandlesFrom"/>

       <param name="quartzHandlesId" value="#{quartzHandlesHome.quartzHandlesId}"/>

     

     

       <navigation from-action="#{quartzEditAction.create}">

          <rule if-outcome="persisted">

             <end-conversation/>

             <redirect view-id="/quartz/QuartzHandles.xhtml"/>   

          </rule>

       </navigation>

       <navigation from-action="#{quartzEditAction.save}">

          <rule if-outcome="updated">

             <end-conversation/>

             <redirect view-id="/quartz/QuartzHandles.xhtml"/>   

          </rule>

       </navigation>  

     

       <navigation from-action="#{quartzEditAction.pause}">

          <rule if-outcome="updated">

             <end-conversation/>

             <redirect view-id="/quartz/QuartzHandles.xhtml"/>

          </rule>

       </navigation>

       <navigation from-action="#{quartzEditAction.resume}">

          <rule if-outcome="updated">

             <end-conversation/>

             <redirect view-id="/quartz/QuartzHandles.xhtml"/>

          </rule>

       </navigation>

       <navigation from-action="#{quartzEditAction.remove}">

          <rule if-outcome="removed">

             <end-conversation/>

             <redirect view-id="/quartz/QuartzHandlesList.xhtml"/>

          </rule>

       </navigation>

     

    </page>

     

     

     

    i got tired of making individual asyc beans to handle each job. hence the added complexity with generics.. but write once,, use it everywhere..... if someone knows how to do this in Seam3 / JavaEE6 i would appreciate a help hint

    hopefully i didnt fat finger anything copying it over.. should get you up and going in no time.

  • 4. Re: using quartz directly
    gebuh Newbie

    wow, thanks Nathan, I have to figure out something that's on fire in another part of our app, but when I'm done I'm going to dive into this and update with my progress.

  • 5. Re: using quartz directly
    Roger Mori Newbie

    Hi Nathan:

     

    Nice example.

     

    I would suggest to create a couple of hibernate validator to validate the class and method in order to place them directly into the entity bean.

    I have coded a hibernate class validator, and I can post the code if you want.

     

    If possible please post the code for QuartzHandles.xhtml (+page.xml), and QuartzHandlesList.xhtml. (+ page.xml).

     

    Thank you very much.

     

    Roger.

     

  • 6. Re: using quartz directly
    nathan dennis Expert

    well without showing my ignerance of hibernate validators, i personally have never used them for anything but validating length, allowable characters, and data types. if you have examples by all means share. ill post the other two xhtmls. i had originally attempted to have the validators in a JSF validator class and use the home object as backing for the JSF Edit page. of course that cuased problems because unlike in previous versions of Seam, 2.2.2 you cannot inject straight into a validator class. (my understanding is the functionality appears again in CDI) you have to use Component.getInstance to get the bean in there. if its a home object you of course will find it difficult to get the same instance or even set the ID in the event of an update to an existing object. i dont know what the problem was.. i was under a lot of stress when i wrote that code. ive written 35+ validators like this and never had to include it in a conversation bean like that to get it to work. when i went to get the ID out of the FacesContext i remember nothing went right. So i just abandoned the effort and simplified it by moving it into the same conversation.. and i belive the way the JSF tag was referencing the validator is what was causing it to not actually put the value of Handle in the bean until the form was submitted.. which of course caused a paradox in that it had to be present for the method validator to return all is well. by all means make this better. colaboration is good...

     

     

     

    <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"

        xmlns:s="http://jboss.com/products/seam/taglib"

        xmlns:ui="http://java.sun.com/jsf/facelets"

        xmlns:f="http://java.sun.com/jsf/core"

        xmlns:h="http://java.sun.com/jsf/html"

        xmlns:rich="http://richfaces.org/rich"

        template="../layout/template.xhtml">

     

    <ui:define name="body">

     

        <rich:panel>

            <f:facet name="header">Quartz handles Details</f:facet>

     

            <s:decorate id="id" template="../layout/display.xhtml">

                <ui:define name="label">Id</ui:define>

                <h:outputText value="#{quartzHandlesHome.instance.id}"/>

            </s:decorate>

     

            <s:decorate id="active" template="../layout/display.xhtml">

                <ui:define name="label">Active</ui:define>

                <h:outputText value="#{quartzHandlesHome.instance.active}"/>

            </s:decorate>

     

            <s:decorate id="cron" template="../layout/display.xhtml">

                <ui:define name="label">Cron</ui:define>

                <h:outputText value="#{quartzHandlesHome.instance.cron}"/>

            </s:decorate>

            <s:decorate id="startdate" template="../layout/display.xhtml">

                <ui:define name="label">Startdate</ui:define>

                <h:outputText value="#{quartzHandlesHome.instance.startdate}">

                    <s:convertDateTime type="both" dateStyle="short"/>

                </h:outputText>

            </s:decorate>

            <s:decorate id="enddate" template="../layout/display.xhtml">

                <ui:define name="label">Enddate</ui:define>

                <h:outputText value="#{quartzHandlesHome.instance.enddate}">

                    <s:convertDateTime type="both" dateStyle="short"/>

                </h:outputText>

            </s:decorate>

     

            <s:decorate id="handleName" template="../layout/display.xhtml">

                <ui:define name="label">Handle name</ui:define>

                <h:outputText value="#{quartzHandlesHome.instance.handleName}"/>

            </s:decorate>

     

            <s:decorate id="methodName" template="../layout/display.xhtml">

                <ui:define name="label">Method</ui:define>

                <h:outputText value="#{quartzHandlesHome.instance.methodName}"/>

            </s:decorate>

     

     

     

            <div style="clear:both"/>

     

        </rich:panel>

     

        <div class="actionButtons">

     

            <s:button view="/quartz/QuartzHandlesEdit.xhtml"

                        id="edit"

                     value="Edit"/>

     

            <s:button view="/quartz/#{empty quartzHandlesFrom ? 'QuartzHandlesList' : quartzHandlesFrom}.xhtml"

                        id="done"

                     value="Done"/>

     

        </div>

     

    </ui:define>

     

    </ui:composition>

     

     

    ----pages.xml

     

    <?xml version="1.0" encoding="UTF-8"?>

    <page xmlns="http://jboss.com/products/seam/pages"

          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"

           login-required="true">

     

       <param name="quartzHandlesFrom"/>

       <param name="quartzHandlesId" value="#{quartzHandlesHome.quartzHandlesId}"/>

     

     

    </page>

     

     

     

     

     

     

    <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"

        xmlns:s="http://jboss.com/products/seam/taglib"

        xmlns:ui="http://java.sun.com/jsf/facelets"

        xmlns:f="http://java.sun.com/jsf/core"

        xmlns:h="http://java.sun.com/jsf/html"

        xmlns:rich="http://richfaces.org/rich"

        template="../layout/template.xhtml">

     

    <ui:define name="body">

     

        <h:form id="quartzHandlesSearch" styleClass="edit">

     

            <rich:simpleTogglePanel label="QuartzHandles Search Filter" switchType="ajax">

     

                <s:decorate template="../layout/display.xhtml">

                    <ui:define name="label">Cron</ui:define>

                    <h:inputText id="cron" value="#{quartzHandlesList.quartzHandles.cron}"/>

                </s:decorate>

     

                <s:decorate template="../layout/display.xhtml">

                    <ui:define name="label">Handle name</ui:define>

                    <h:inputText id="handleName" value="#{quartzHandlesList.quartzHandles.handleName}"/>

                </s:decorate>

              

                <s:decorate template="../layout/display.xhtml">

                    <ui:define name="label">Method Name</ui:define>

                    <h:inputText id="handleName" value="#{quartzHandlesList.quartzHandles.methodName}"/>

                </s:decorate>

             

                <s:decorate template="../layout/display.xhtml">

                    <ui:define name="label">Match</ui:define>

                    <h:selectOneRadio id="logic" value="#{quartzHandlesList.restrictionLogicOperator}" styleClass="radio">

                        <f:selectItem itemLabel="All" itemValue="and"/>

                        <f:selectItem itemLabel="Any" itemValue="or"/>

                    </h:selectOneRadio>

                </s:decorate>

     

            </rich:simpleTogglePanel>

     

            <div class="actionButtons">

                <h:commandButton id="search" value="Search" action="/quartz/QuartzHandlesList.xhtml"/>

                <s:button id="reset" value="Reset" includePageParams="false"/>

            </div>

     

        </h:form>

     

        <rich:panel>

            <f:facet name="header">QuartzHandles Search Results (#{empty quartzHandlesList.resultList ? 0 : (quartzHandlesList.paginated ? quartzHandlesList.resultCount : quartzHandlesList.resultList.size)})</f:facet>

        <div class="results" id="quartzHandlesList">

     

        <h:outputText value="The quartzHandles search returned no results."

                   rendered="#{empty quartzHandlesList.resultList}"/>

     

        <rich:dataTable id="quartzHandlesList"

                    var="_quartzHandles"

                  value="#{quartzHandlesList.resultList}"

               rendered="#{not empty quartzHandlesList.resultList}">

            <h:column>

                <f:facet name="header">

                    <ui:include src="../layout/sort.xhtml">

                        <ui:param name="entityList" value="#{quartzHandlesList}"/>

                        <ui:param name="propertyLabel" value="Id"/>

                        <ui:param name="propertyPath" value="quartzHandles.id"/>

                    </ui:include>

                </f:facet>

                <h:outputText value="#{_quartzHandles.id}"/>

            </h:column>

            <h:column>

                <f:facet name="header">

                    <ui:include src="../layout/sort.xhtml">

                        <ui:param name="entityList" value="#{quartzHandlesList}"/>

                        <ui:param name="propertyLabel" value="Cron"/>

                        <ui:param name="propertyPath" value="quartzHandles.cron"/>

                    </ui:include>

                </f:facet>

                <h:outputText value="#{_quartzHandles.cron}"/>

            </h:column>

              <h:column>

                <f:facet name="header">

                    <ui:include src="../layout/sort.xhtml">

                        <ui:param name="entityList" value="#{quartzHandlesList}"/>

                        <ui:param name="propertyLabel" value="Startdate"/>

                        <ui:param name="propertyPath" value="quartzHandles.startdate"/>

                    </ui:include>

                </f:facet>

                <h:outputText value="#{_quartzHandles.startdate}">

                    <s:convertDateTime type="both" dateStyle="short"/>

                </h:outputText>

            </h:column>       

            <h:column>

                <f:facet name="header">

                    <ui:include src="../layout/sort.xhtml">

                        <ui:param name="entityList" value="#{quartzHandlesList}"/>

                        <ui:param name="propertyLabel" value="Enddate"/>

                        <ui:param name="propertyPath" value="quartzHandles.enddate"/>

                    </ui:include>

                </f:facet>

                <h:outputText value="#{_quartzHandles.enddate}">

                    <s:convertDateTime type="both" dateStyle="short"/>

                </h:outputText>

            </h:column>

     

            <h:column>

                <f:facet name="header">

                    <ui:include src="../layout/sort.xhtml">

                        <ui:param name="entityList" value="#{quartzHandlesList}"/>

                        <ui:param name="propertyLabel" value="Handle name"/>

                        <ui:param name="propertyPath" value="quartzHandles.handleName"/>

                    </ui:include>

                </f:facet>

                <h:outputText value="#{_quartzHandles.handleName}"/>

            </h:column>

            <h:column>

                <f:facet name="header">

                    <ui:include src="../layout/sort.xhtml">

                        <ui:param name="entityList" value="#{quartzHandlesList}"/>

                        <ui:param name="propertyLabel" value="Method"/>

                        <ui:param name="propertyPath" value="quartzHandles.methodName"/>

                    </ui:include>

                </f:facet>

                <h:outputText value="#{_quartzHandles.methodName}"/>

            </h:column>       

         

            <rich:column styleClass="action">

                <f:facet name="header">Action</f:facet>

                <s:link view="/quartz/#{empty from ? 'QuartzHandles' : from}.xhtml"

                       value="#{empty from ? 'View' : 'Select'}"

                 propagation="#{empty from ? 'none' : 'default'}"

                          id="quartzHandlesViewId">

                    <f:param name="quartzHandlesId"

                            value="#{_quartzHandles.id}"/>

                </s:link>

                #{' '}

                <s:link view="/quartz/QuartzHandlesEdit.xhtml"

                       value="Edit"

                 propagation="none"

                          id="quartzHandlesEdit"

                    rendered="#{empty from}">

                    <f:param name="quartzHandlesId"

                            value="#{_quartzHandles.id}"/>

                </s:link>

            </rich:column>

        </rich:dataTable>

     

        </div>

        </rich:panel>

     

        <div class="tableControl">

     

            <s:link view="/quartz/QuartzHandlesList.xhtml"

                rendered="#{quartzHandlesList.previousExists}"

                   value="#{messages.left}#{messages.left} First Page"

                      id="firstPage">

              <f:param name="firstResult" value="0"/>

            </s:link>

     

            <s:link view="/quartz/QuartzHandlesList.xhtml"

                rendered="#{quartzHandlesList.previousExists}"

                   value="#{messages.left} Previous Page"

                      id="previousPage">

                <f:param name="firstResult"

                        value="#{quartzHandlesList.previousFirstResult}"/>

            </s:link>

     

            <s:link view="/quartz/QuartzHandlesList.xhtml"

                rendered="#{quartzHandlesList.nextExists}"

                   value="Next Page #{messages.right}"

                      id="nextPage">

                <f:param name="firstResult"

                        value="#{quartzHandlesList.nextFirstResult}"/>

            </s:link>

     

            <s:link view="/quartz/QuartzHandlesList.xhtml"

                rendered="#{quartzHandlesList.nextExists}"

                   value="Last Page #{messages.right}#{messages.right}"

                      id="lastPage">

                <f:param name="firstResult"

                        value="#{quartzHandlesList.lastFirstResult}"/>

            </s:link>

     

        </div>

     

        <s:div styleClass="actionButtons" rendered="#{empty from}">

            <s:button view="/quartz/QuartzHandlesEdit.xhtml"

                        id="create"

               propagation="none"

                     value="Create quartzHandles">

                <f:param name="quartzHandlesId"/>

            </s:button>

        </s:div>

     

    </ui:define>

     

    </ui:composition>

     

     

     

     

     

     

     

     

     

    ------------pages.xml

     

     

    <?xml version="1.0" encoding="UTF-8"?>

    <page xmlns="http://jboss.com/products/seam/pages"

          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"      

          login-required="true">

     

      

       <param name="firstResult" value="#{quartzHandlesList.firstResult}"/>

       <param name="sort" value="#{quartzHandlesList.orderColumn}"/>

       <param name="dir" value="#{quartzHandlesList.orderDirection}"/>

       <param name="logic" value="#{quartzHandlesList.restrictionLogicOperator}"/>

     

       <param name="from"/>

       <param name="cron" value="#{quartzHandlesList.quartzHandles.cron}"/>

       <param name="handleName" value="#{quartzHandlesList.quartzHandles.handleName}"/>

       <param name="methodName" value="#{quartzHandlesList.quartzHandles.methodName}"/>

    </page>

  • 7. Re: using quartz directly
    Roger Mori Newbie

    Hi Nathan:

     

    Listed below is the code for the hibernate validator that check if a class exists in your seam application.

     

     

    Thank you.

     

    Roger.

     

     

    Usage

     

    @Length(max = 512)
    @ClassExists
    @Column(name = "CLASS_NAME", length = 532, nullable = true)
    public String getFullClassName() {
      return fullClassName;
    }
    public void setFullClassName(String fullClassName) {
      this.fullClassName = fullClassName;
    }

     

    Hibernate Validator

    Create a package in your main directory and add the following three *.java classes; finally, add the last utility class.

     

    package-info.java

    package com.dpn.model.validator;

     

    ClassExists.java

     

    package com.dpn.model.validator;

    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    import org.hibernate.validator.ValidatorClass;
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @ValidatorClass(ClassExistsValidator.class)
    public @interface ClassExists {
    String message() default " invalid class";
    }

     

    ClassExistsValidator.java

     

    package com.dpn.model.validator;

    import org.hibernate.validator.Validator;
    import org.jboss.seam.log.LogProvider;
    import org.jboss.seam.log.Logging;

    import bsh.EvalError;
    import bsh.Interpreter;

    import com.hersys.utils.String.StringUtils;
    import com.hersys.utils.reflection.FixedDynamicClassLoader;

     

     

    public class ClassExistsValidator  implements Validator<ClassExists>, java.io.Serializable{
    private static final long serialVersionUID = 1L;
    private static final LogProvider log = Logging.getLogProvider(ClassExistsValidator.class);

    public void initialize(ClassExists configuration) {
    }

    public boolean isValid(Object value) {
      log.info("ClassExistValidator has been called");
      if (value == null) {
       log.info("Validation skipped because value is blank or null");
       return true;
      }
      String fullClassName = (String)value;
      log.info("value to validate is " + fullClassName);
      if (fullClassName == null) {
       log.info("svalue is null");
       return false;
      }
         try {
       Class o = FixedDynamicClassLoader.loadClass(fullClassName);
      } catch (ClassNotFoundException e1) {
       log.info("Validation failed: " + e1.getMessage());
       return false;
      }
         return true;
    }

    }

    FixedDynamicClassLoader.java

     

    package com.hersys.utils.reflection;

    import com.hersys.utils.String.StringUtils;

    public class FixedDynamicClassLoader implements java.io.Serializable {

      private static final long serialVersionUID = 1L;

    public static Class loadClass(String fullClassName) throws ClassNotFoundException {
      if (StringUtils.isEmpty(fullClassName)) {
       throw new IllegalArgumentException("empty fullClassName");
      }
      ClassLoader loader = Thread.currentThread().getContextClassLoader();
      return      loader.loadClass(fullClassName);  
    }

    }

     

     

     

  • 8. Re: using quartz directly
    gebuh Newbie

    I'm going to demonstrate my ignorance of hibernate validators also, what exactly do they do?

     

    Nathan; are you using the jobstore(storing jobs in db)?  If so, how does that interface with your quartz_handles table/entity?

  • 9. Re: using quartz directly
    nathan dennis Expert

    The hibernate validator he provided creates an annotation to handle that validation. This is a much prettier way of handling the validation. Im planning on incorporating it into my production code.. as well.

     

    Yes im using a job store. Handles are stored in the db. The object is stored in the byte array field. The interfacing between my entity and the ones provided by quartz is handled automatically. The triggers are stored in the quartz ds and the quartz handles are stored in the other. In my project I was sharing tables across all projects on that appserver for quartz. Don't get tripped up by the seperation of the data sources. The beauty of using the seam quartz handle is most of the dirt work is handled automatically. Yes this is an example of a non memory jobstore. The app server can go through a power cycle and the jobs will come right back.just try out the code. Its a working example.

  • 10. Re: using quartz directly
    nathan dennis Expert

    roger i just now got around to trying out your vaildator. i continue to learn new things... good work and thanks for showing me. its a much cleaner solution of validating the class. +1