Search in sources :

Example 1 with ConnectionProvider

use of org.quartz.utils.ConnectionProvider in project spring-framework by spring-projects.

the class LocalDataSourceJobStore method initialize.

@Override
public void initialize(ClassLoadHelper loadHelper, SchedulerSignaler signaler) throws SchedulerConfigException {
    // Absolutely needs thread-bound DataSource to initialize.
    this.dataSource = SchedulerFactoryBean.getConfigTimeDataSource();
    if (this.dataSource == null) {
        throw new SchedulerConfigException("No local DataSource found for configuration - " + "'dataSource' property must be set on SchedulerFactoryBean");
    }
    // Configure transactional connection settings for Quartz.
    setDataSource(TX_DATA_SOURCE_PREFIX + getInstanceName());
    setDontSetAutoCommitFalse(true);
    // Register transactional ConnectionProvider for Quartz.
    DBConnectionManager.getInstance().addConnectionProvider(TX_DATA_SOURCE_PREFIX + getInstanceName(), new ConnectionProvider() {

        @Override
        public Connection getConnection() throws SQLException {
            // Return a transactional Connection, if any.
            return DataSourceUtils.doGetConnection(dataSource);
        }

        @Override
        public void shutdown() {
        // Do nothing - a Spring-managed DataSource has its own lifecycle.
        }

        @Override
        public void initialize() {
        // Do nothing - a Spring-managed DataSource has its own lifecycle.
        }
    });
    // Non-transactional DataSource is optional: fall back to default
    // DataSource if not explicitly specified.
    DataSource nonTxDataSource = SchedulerFactoryBean.getConfigTimeNonTransactionalDataSource();
    final DataSource nonTxDataSourceToUse = (nonTxDataSource != null ? nonTxDataSource : this.dataSource);
    // Configure non-transactional connection settings for Quartz.
    setNonManagedTXDataSource(NON_TX_DATA_SOURCE_PREFIX + getInstanceName());
    // Register non-transactional ConnectionProvider for Quartz.
    DBConnectionManager.getInstance().addConnectionProvider(NON_TX_DATA_SOURCE_PREFIX + getInstanceName(), new ConnectionProvider() {

        @Override
        public Connection getConnection() throws SQLException {
            // Always return a non-transactional Connection.
            return nonTxDataSourceToUse.getConnection();
        }

        @Override
        public void shutdown() {
        // Do nothing - a Spring-managed DataSource has its own lifecycle.
        }

        @Override
        public void initialize() {
        // Do nothing - a Spring-managed DataSource has its own lifecycle.
        }
    });
    // No, if HSQL is the platform, we really don't want to use locks...
    try {
        String productName = JdbcUtils.extractDatabaseMetaData(this.dataSource, DatabaseMetaData::getDatabaseProductName);
        productName = JdbcUtils.commonDatabaseName(productName);
        if (productName != null && productName.toLowerCase().contains("hsql")) {
            setUseDBLocks(false);
            setLockHandler(new SimpleSemaphore());
        }
    } catch (MetaDataAccessException ex) {
        logWarnIfNonZero(1, "Could not detect database type. Assuming locks can be taken.");
    }
    super.initialize(loadHelper, signaler);
}
Also used : MetaDataAccessException(org.springframework.jdbc.support.MetaDataAccessException) SimpleSemaphore(org.quartz.impl.jdbcjobstore.SimpleSemaphore) SQLException(java.sql.SQLException) Connection(java.sql.Connection) DatabaseMetaData(java.sql.DatabaseMetaData) SchedulerConfigException(org.quartz.SchedulerConfigException) ConnectionProvider(org.quartz.utils.ConnectionProvider) DataSource(javax.sql.DataSource)

Example 2 with ConnectionProvider

use of org.quartz.utils.ConnectionProvider in project weicoder by wdcode.

the class StdSchedulerFactory method instantiate.

private Scheduler instantiate() throws SchedulerException {
    if (cfg == null) {
        initialize();
    }
    if (initException != null) {
        throw initException;
    }
    JobStore js = null;
    ThreadPool tp = null;
    QuartzScheduler qs = null;
    DBConnectionManager dbMgr = null;
    String instanceIdGeneratorClass = null;
    Properties tProps = null;
    String userTXLocation = null;
    boolean wrapJobInTx = false;
    boolean autoId = false;
    long idleWaitTime = -1;
    // 15 secs
    long dbFailureRetry = 15000L;
    String classLoadHelperClass;
    String jobFactoryClass;
    ThreadExecutor threadExecutor;
    SchedulerRepository schedRep = SchedulerRepository.getInstance();
    // Get Scheduler Properties
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    String schedName = cfg.getStringProperty(PROP_SCHED_INSTANCE_NAME, "QuartzScheduler");
    String threadName = cfg.getStringProperty(PROP_SCHED_THREAD_NAME, schedName + "_QuartzSchedulerThread");
    String schedInstId = cfg.getStringProperty(PROP_SCHED_INSTANCE_ID, DEFAULT_INSTANCE_ID);
    if (schedInstId.equals(AUTO_GENERATE_INSTANCE_ID)) {
        autoId = true;
        instanceIdGeneratorClass = cfg.getStringProperty(PROP_SCHED_INSTANCE_ID_GENERATOR_CLASS, "org.quartz.simpl.SimpleInstanceIdGenerator");
    } else if (schedInstId.equals(SYSTEM_PROPERTY_AS_INSTANCE_ID)) {
        autoId = true;
        instanceIdGeneratorClass = "org.quartz.simpl.SystemPropertyInstanceIdGenerator";
    }
    userTXLocation = cfg.getStringProperty(PROP_SCHED_USER_TX_URL, userTXLocation);
    if (userTXLocation != null && userTXLocation.trim().length() == 0) {
        userTXLocation = null;
    }
    classLoadHelperClass = cfg.getStringProperty(PROP_SCHED_CLASS_LOAD_HELPER_CLASS, "org.quartz.simpl.CascadingClassLoadHelper");
    wrapJobInTx = cfg.getBooleanProperty(PROP_SCHED_WRAP_JOB_IN_USER_TX, wrapJobInTx);
    jobFactoryClass = cfg.getStringProperty(PROP_SCHED_JOB_FACTORY_CLASS, null);
    idleWaitTime = cfg.getLongProperty(PROP_SCHED_IDLE_WAIT_TIME, idleWaitTime);
    if (idleWaitTime > -1 && idleWaitTime < 1000) {
        throw new SchedulerException("org.quartz.scheduler.idleWaitTime of less than 1000ms is not legal.");
    }
    dbFailureRetry = cfg.getLongProperty(PROP_SCHED_DB_FAILURE_RETRY_INTERVAL, dbFailureRetry);
    if (dbFailureRetry < 0) {
        throw new SchedulerException(PROP_SCHED_DB_FAILURE_RETRY_INTERVAL + " of less than 0 ms is not legal.");
    }
    boolean makeSchedulerThreadDaemon = cfg.getBooleanProperty(PROP_SCHED_MAKE_SCHEDULER_THREAD_DAEMON);
    boolean threadsInheritInitalizersClassLoader = cfg.getBooleanProperty(PROP_SCHED_SCHEDULER_THREADS_INHERIT_CONTEXT_CLASS_LOADER_OF_INITIALIZING_THREAD);
    long batchTimeWindow = cfg.getLongProperty(PROP_SCHED_BATCH_TIME_WINDOW, 0L);
    int maxBatchSize = cfg.getIntProperty(PROP_SCHED_MAX_BATCH_SIZE, 1);
    boolean interruptJobsOnShutdown = cfg.getBooleanProperty(PROP_SCHED_INTERRUPT_JOBS_ON_SHUTDOWN, false);
    boolean interruptJobsOnShutdownWithWait = cfg.getBooleanProperty(PROP_SCHED_INTERRUPT_JOBS_ON_SHUTDOWN_WITH_WAIT, false);
    boolean jmxExport = cfg.getBooleanProperty(PROP_SCHED_JMX_EXPORT);
    String jmxObjectName = cfg.getStringProperty(PROP_SCHED_JMX_OBJECT_NAME);
    boolean jmxProxy = cfg.getBooleanProperty(PROP_SCHED_JMX_PROXY);
    String jmxProxyClass = cfg.getStringProperty(PROP_SCHED_JMX_PROXY_CLASS);
    boolean rmiExport = cfg.getBooleanProperty(PROP_SCHED_RMI_EXPORT, false);
    boolean rmiProxy = cfg.getBooleanProperty(PROP_SCHED_RMI_PROXY, false);
    String rmiHost = cfg.getStringProperty(PROP_SCHED_RMI_HOST, "localhost");
    int rmiPort = cfg.getIntProperty(PROP_SCHED_RMI_PORT, 1099);
    int rmiServerPort = cfg.getIntProperty(PROP_SCHED_RMI_SERVER_PORT, -1);
    String rmiCreateRegistry = cfg.getStringProperty(PROP_SCHED_RMI_CREATE_REGISTRY, QuartzSchedulerResources.CREATE_REGISTRY_NEVER);
    String rmiBindName = cfg.getStringProperty(PROP_SCHED_RMI_BIND_NAME);
    if (jmxProxy && rmiProxy) {
        throw new SchedulerConfigException("Cannot proxy both RMI and JMX.");
    }
    boolean managementRESTServiceEnabled = cfg.getBooleanProperty(MANAGEMENT_REST_SERVICE_ENABLED, false);
    String managementRESTServiceHostAndPort = cfg.getStringProperty(MANAGEMENT_REST_SERVICE_HOST_PORT, "0.0.0.0:9889");
    Properties schedCtxtProps = cfg.getPropertyGroup(PROP_SCHED_CONTEXT_PREFIX, true);
    // ~~~~~~~~~~~~~~~~~~
    if (rmiProxy) {
        if (autoId) {
            schedInstId = DEFAULT_INSTANCE_ID;
        }
        String uid = (rmiBindName == null) ? QuartzSchedulerResources.getUniqueIdentifier(schedName, schedInstId) : rmiBindName;
        RemoteScheduler remoteScheduler = new RemoteScheduler(uid, rmiHost, rmiPort);
        schedRep.bind(remoteScheduler);
        return remoteScheduler;
    }
    // Create class load helper
    ClassLoadHelper loadHelper = null;
    try {
        loadHelper = (ClassLoadHelper) loadClass(classLoadHelperClass).getDeclaredConstructor().newInstance();
    } catch (Exception e) {
        throw new SchedulerConfigException("Unable to instantiate class load helper class: " + e.getMessage(), e);
    }
    loadHelper.initialize();
    // ~~~~~~~~~~~~~~~~~~
    if (jmxProxy) {
        if (autoId) {
            schedInstId = DEFAULT_INSTANCE_ID;
        }
        if (jmxProxyClass == null) {
            throw new SchedulerConfigException("No JMX Proxy Scheduler class provided");
        }
        RemoteMBeanScheduler jmxScheduler = null;
        try {
            jmxScheduler = (RemoteMBeanScheduler) loadHelper.loadClass(jmxProxyClass).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new SchedulerConfigException("Unable to instantiate RemoteMBeanScheduler class.", e);
        }
        if (jmxObjectName == null) {
            jmxObjectName = QuartzSchedulerResources.generateJMXObjectName(schedName, schedInstId);
        }
        jmxScheduler.setSchedulerObjectName(jmxObjectName);
        tProps = cfg.getPropertyGroup(PROP_SCHED_JMX_PROXY, true);
        try {
            setBeanProps(jmxScheduler, tProps);
        } catch (Exception e) {
            initException = new SchedulerException("RemoteMBeanScheduler class '" + jmxProxyClass + "' props could not be configured.", e);
            throw initException;
        }
        jmxScheduler.initialize();
        schedRep.bind(jmxScheduler);
        return jmxScheduler;
    }
    JobFactory jobFactory = null;
    if (jobFactoryClass != null) {
        try {
            jobFactory = (JobFactory) loadHelper.loadClass(jobFactoryClass).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new SchedulerConfigException("Unable to instantiate JobFactory class: " + e.getMessage(), e);
        }
        tProps = cfg.getPropertyGroup(PROP_SCHED_JOB_FACTORY_PREFIX, true);
        try {
            setBeanProps(jobFactory, tProps);
        } catch (Exception e) {
            initException = new SchedulerException("JobFactory class '" + jobFactoryClass + "' props could not be configured.", e);
            throw initException;
        }
    }
    InstanceIdGenerator instanceIdGenerator = null;
    if (instanceIdGeneratorClass != null) {
        try {
            instanceIdGenerator = (InstanceIdGenerator) loadHelper.loadClass(instanceIdGeneratorClass).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new SchedulerConfigException("Unable to instantiate InstanceIdGenerator class: " + e.getMessage(), e);
        }
        tProps = cfg.getPropertyGroup(PROP_SCHED_INSTANCE_ID_GENERATOR_PREFIX, true);
        try {
            setBeanProps(instanceIdGenerator, tProps);
        } catch (Exception e) {
            initException = new SchedulerException("InstanceIdGenerator class '" + instanceIdGeneratorClass + "' props could not be configured.", e);
            throw initException;
        }
    }
    // Get ThreadPool Properties
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    String tpClass = cfg.getStringProperty(PROP_THREAD_POOL_CLASS, SimpleThreadPool.class.getName());
    if (tpClass == null) {
        initException = new SchedulerException("ThreadPool class not specified. ");
        throw initException;
    }
    try {
        tp = (ThreadPool) loadHelper.loadClass(tpClass).getDeclaredConstructor().newInstance();
    } catch (Exception e) {
        initException = new SchedulerException("ThreadPool class '" + tpClass + "' could not be instantiated.", e);
        throw initException;
    }
    tProps = cfg.getPropertyGroup(PROP_THREAD_POOL_PREFIX, true);
    try {
        setBeanProps(tp, tProps);
    } catch (Exception e) {
        initException = new SchedulerException("ThreadPool class '" + tpClass + "' props could not be configured.", e);
        throw initException;
    }
    // Get JobStore Properties
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    String jsClass = cfg.getStringProperty(PROP_JOB_STORE_CLASS, RAMJobStore.class.getName());
    if (jsClass == null) {
        initException = new SchedulerException("JobStore class not specified. ");
        throw initException;
    }
    try {
        js = (JobStore) loadHelper.loadClass(jsClass).getDeclaredConstructor().newInstance();
    } catch (Exception e) {
        initException = new SchedulerException("JobStore class '" + jsClass + "' could not be instantiated.", e);
        throw initException;
    }
    SchedulerDetailsSetter.setDetails(js, schedName, schedInstId);
    tProps = cfg.getPropertyGroup(PROP_JOB_STORE_PREFIX, true, new String[] { PROP_JOB_STORE_LOCK_HANDLER_PREFIX });
    try {
        setBeanProps(js, tProps);
    } catch (Exception e) {
        initException = new SchedulerException("JobStore class '" + jsClass + "' props could not be configured.", e);
        throw initException;
    }
    if (js instanceof JobStoreSupport) {
        // Install custom lock handler (Semaphore)
        String lockHandlerClass = cfg.getStringProperty(PROP_JOB_STORE_LOCK_HANDLER_CLASS);
        if (lockHandlerClass != null) {
            try {
                Semaphore lockHandler = (Semaphore) loadHelper.loadClass(lockHandlerClass).getDeclaredConstructor().newInstance();
                tProps = cfg.getPropertyGroup(PROP_JOB_STORE_LOCK_HANDLER_PREFIX, true);
                // If this lock handler requires the table prefix, add it to its properties.
                if (lockHandler instanceof TablePrefixAware) {
                    tProps.setProperty(PROP_TABLE_PREFIX, ((JobStoreSupport) js).getTablePrefix());
                    tProps.setProperty(PROP_SCHED_NAME, schedName);
                }
                try {
                    setBeanProps(lockHandler, tProps);
                } catch (Exception e) {
                    initException = new SchedulerException("JobStore LockHandler class '" + lockHandlerClass + "' props could not be configured.", e);
                    throw initException;
                }
                ((JobStoreSupport) js).setLockHandler(lockHandler);
                getLog().info("Using custom data access locking (synchronization): " + lockHandlerClass);
            } catch (Exception e) {
                initException = new SchedulerException("JobStore LockHandler class '" + lockHandlerClass + "' could not be instantiated.", e);
                throw initException;
            }
        }
    }
    // Set up any DataSources
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    String[] dsNames = cfg.getPropertyGroups(PROP_DATASOURCE_PREFIX);
    for (int i = 0; i < dsNames.length; i++) {
        PropertiesParser pp = new PropertiesParser(cfg.getPropertyGroup(PROP_DATASOURCE_PREFIX + "." + dsNames[i], true));
        String cpClass = pp.getStringProperty(PROP_CONNECTION_PROVIDER_CLASS, null);
        // custom connectionProvider...
        if (cpClass != null) {
            ConnectionProvider cp = null;
            try {
                cp = (ConnectionProvider) loadHelper.loadClass(cpClass).getDeclaredConstructor().newInstance();
            } catch (Exception e) {
                initException = new SchedulerException("ConnectionProvider class '" + cpClass + "' could not be instantiated.", e);
                throw initException;
            }
            try {
                // remove the class name, so it isn't attempted to be set
                pp.getUnderlyingProperties().remove(PROP_CONNECTION_PROVIDER_CLASS);
                if (cp instanceof PoolingConnectionProvider) {
                    populateProviderWithExtraProps((PoolingConnectionProvider) cp, pp.getUnderlyingProperties());
                } else {
                    setBeanProps(cp, pp.getUnderlyingProperties());
                }
                cp.initialize();
            } catch (Exception e) {
                initException = new SchedulerException("ConnectionProvider class '" + cpClass + "' props could not be configured.", e);
                throw initException;
            }
            dbMgr = DBConnectionManager.getInstance();
            dbMgr.addConnectionProvider(dsNames[i], cp);
        } else {
            String dsJndi = pp.getStringProperty(PROP_DATASOURCE_JNDI_URL, null);
            if (dsJndi != null) {
                boolean dsAlwaysLookup = pp.getBooleanProperty(PROP_DATASOURCE_JNDI_ALWAYS_LOOKUP);
                String dsJndiInitial = pp.getStringProperty(PROP_DATASOURCE_JNDI_INITIAL);
                String dsJndiProvider = pp.getStringProperty(PROP_DATASOURCE_JNDI_PROVDER);
                String dsJndiPrincipal = pp.getStringProperty(PROP_DATASOURCE_JNDI_PRINCIPAL);
                String dsJndiCredentials = pp.getStringProperty(PROP_DATASOURCE_JNDI_CREDENTIALS);
                Properties props = null;
                if (null != dsJndiInitial || null != dsJndiProvider || null != dsJndiPrincipal || null != dsJndiCredentials) {
                    props = new Properties();
                    if (dsJndiInitial != null) {
                        props.put(PROP_DATASOURCE_JNDI_INITIAL, dsJndiInitial);
                    }
                    if (dsJndiProvider != null) {
                        props.put(PROP_DATASOURCE_JNDI_PROVDER, dsJndiProvider);
                    }
                    if (dsJndiPrincipal != null) {
                        props.put(PROP_DATASOURCE_JNDI_PRINCIPAL, dsJndiPrincipal);
                    }
                    if (dsJndiCredentials != null) {
                        props.put(PROP_DATASOURCE_JNDI_CREDENTIALS, dsJndiCredentials);
                    }
                }
                JNDIConnectionProvider cp = new JNDIConnectionProvider(dsJndi, props, dsAlwaysLookup);
                dbMgr = DBConnectionManager.getInstance();
                dbMgr.addConnectionProvider(dsNames[i], cp);
            } else {
                String poolingProvider = pp.getStringProperty(PoolingConnectionProvider.POOLING_PROVIDER);
                String dsDriver = pp.getStringProperty(PoolingConnectionProvider.DB_DRIVER);
                String dsURL = pp.getStringProperty(PoolingConnectionProvider.DB_URL);
                if (dsDriver == null) {
                    initException = new SchedulerException("Driver not specified for DataSource: " + dsNames[i]);
                    throw initException;
                }
                if (dsURL == null) {
                    initException = new SchedulerException("DB URL not specified for DataSource: " + dsNames[i]);
                    throw initException;
                }
                // the c3p0 and hikaricp libraries
                if (poolingProvider != null && poolingProvider.equals(PoolingConnectionProvider.POOLING_PROVIDER_HIKARICP)) {
                    cpClass = "org.quartz.utils.HikariCpPoolingConnectionProvider";
                } else {
                    cpClass = "org.quartz.utils.C3p0PoolingConnectionProvider";
                }
                log.info("Using ConnectionProvider class '" + cpClass + "' for data source '" + dsNames[i] + "'");
                try {
                    ConnectionProvider cp = null;
                    try {
                        Constructor<?> constructor = loadHelper.loadClass(cpClass).getConstructor(Properties.class);
                        cp = (ConnectionProvider) constructor.newInstance(pp.getUnderlyingProperties());
                    } catch (Exception e) {
                        initException = new SchedulerException("ConnectionProvider class '" + cpClass + "' could not be instantiated.", e);
                        throw initException;
                    }
                    dbMgr = DBConnectionManager.getInstance();
                    dbMgr.addConnectionProvider(dsNames[i], cp);
                    // Populate the underlying C3P0/HikariCP data source pool properties
                    populateProviderWithExtraProps((PoolingConnectionProvider) cp, pp.getUnderlyingProperties());
                } catch (Exception sqle) {
                    initException = new SchedulerException("Could not initialize DataSource: " + dsNames[i], sqle);
                    throw initException;
                }
            }
        }
    }
    // Set up any SchedulerPlugins
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    String[] pluginNames = cfg.getPropertyGroups(PROP_PLUGIN_PREFIX);
    SchedulerPlugin[] plugins = new SchedulerPlugin[pluginNames.length];
    for (int i = 0; i < pluginNames.length; i++) {
        Properties pp = cfg.getPropertyGroup(PROP_PLUGIN_PREFIX + "." + pluginNames[i], true);
        String plugInClass = pp.getProperty(PROP_PLUGIN_CLASS, null);
        if (plugInClass == null) {
            initException = new SchedulerException("SchedulerPlugin class not specified for plugin '" + pluginNames[i] + "'");
            throw initException;
        }
        SchedulerPlugin plugin = null;
        try {
            plugin = (SchedulerPlugin) loadHelper.loadClass(plugInClass).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            initException = new SchedulerException("SchedulerPlugin class '" + plugInClass + "' could not be instantiated.", e);
            throw initException;
        }
        try {
            setBeanProps(plugin, pp);
        } catch (Exception e) {
            initException = new SchedulerException("JobStore SchedulerPlugin '" + plugInClass + "' props could not be configured.", e);
            throw initException;
        }
        plugins[i] = plugin;
    }
    // Set up any JobListeners
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Class<?>[] strArg = new Class[] { String.class };
    String[] jobListenerNames = cfg.getPropertyGroups(PROP_JOB_LISTENER_PREFIX);
    JobListener[] jobListeners = new JobListener[jobListenerNames.length];
    for (int i = 0; i < jobListenerNames.length; i++) {
        Properties lp = cfg.getPropertyGroup(PROP_JOB_LISTENER_PREFIX + "." + jobListenerNames[i], true);
        String listenerClass = lp.getProperty(PROP_LISTENER_CLASS, null);
        if (listenerClass == null) {
            initException = new SchedulerException("JobListener class not specified for listener '" + jobListenerNames[i] + "'");
            throw initException;
        }
        JobListener listener = null;
        try {
            listener = (JobListener) loadHelper.loadClass(listenerClass).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            initException = new SchedulerException("JobListener class '" + listenerClass + "' could not be instantiated.", e);
            throw initException;
        }
        try {
            Method nameSetter = null;
            try {
                nameSetter = listener.getClass().getMethod("setName", strArg);
            } catch (NoSuchMethodException ignore) {
            /* do nothing */
            }
            if (nameSetter != null) {
                nameSetter.invoke(listener, new Object[] { jobListenerNames[i] });
            }
            setBeanProps(listener, lp);
        } catch (Exception e) {
            initException = new SchedulerException("JobListener '" + listenerClass + "' props could not be configured.", e);
            throw initException;
        }
        jobListeners[i] = listener;
    }
    // Set up any TriggerListeners
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    String[] triggerListenerNames = cfg.getPropertyGroups(PROP_TRIGGER_LISTENER_PREFIX);
    TriggerListener[] triggerListeners = new TriggerListener[triggerListenerNames.length];
    for (int i = 0; i < triggerListenerNames.length; i++) {
        Properties lp = cfg.getPropertyGroup(PROP_TRIGGER_LISTENER_PREFIX + "." + triggerListenerNames[i], true);
        String listenerClass = lp.getProperty(PROP_LISTENER_CLASS, null);
        if (listenerClass == null) {
            initException = new SchedulerException("TriggerListener class not specified for listener '" + triggerListenerNames[i] + "'");
            throw initException;
        }
        TriggerListener listener = null;
        try {
            listener = (TriggerListener) loadHelper.loadClass(listenerClass).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            initException = new SchedulerException("TriggerListener class '" + listenerClass + "' could not be instantiated.", e);
            throw initException;
        }
        try {
            Method nameSetter = null;
            try {
                nameSetter = listener.getClass().getMethod("setName", strArg);
            } catch (NoSuchMethodException ignore) {
            /* do nothing */
            }
            if (nameSetter != null) {
                nameSetter.invoke(listener, new Object[] { triggerListenerNames[i] });
            }
            setBeanProps(listener, lp);
        } catch (Exception e) {
            initException = new SchedulerException("TriggerListener '" + listenerClass + "' props could not be configured.", e);
            throw initException;
        }
        triggerListeners[i] = listener;
    }
    boolean tpInited = false;
    boolean qsInited = false;
    // Get ThreadExecutor Properties
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    String threadExecutorClass = cfg.getStringProperty(PROP_THREAD_EXECUTOR_CLASS);
    if (threadExecutorClass != null) {
        tProps = cfg.getPropertyGroup(PROP_THREAD_EXECUTOR, true);
        try {
            threadExecutor = (ThreadExecutor) loadHelper.loadClass(threadExecutorClass).getDeclaredConstructor().newInstance();
            log.info("Using custom implementation for ThreadExecutor: " + threadExecutorClass);
            setBeanProps(threadExecutor, tProps);
        } catch (Exception e) {
            initException = new SchedulerException("ThreadExecutor class '" + threadExecutorClass + "' could not be instantiated.", e);
            throw initException;
        }
    } else {
        log.info("Using default implementation for ThreadExecutor");
        threadExecutor = new DefaultThreadExecutor();
    }
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    try {
        // Create correct run-shell factory...
        JobRunShellFactory jrsf = null;
        if (userTXLocation != null) {
            UserTransactionHelper.setUserTxLocation(userTXLocation);
        }
        if (wrapJobInTx) {
            jrsf = new JTAJobRunShellFactory();
        } else {
            jrsf = new JTAAnnotationAwareJobRunShellFactory();
        }
        if (autoId) {
            try {
                schedInstId = DEFAULT_INSTANCE_ID;
                if (js.isClustered()) {
                    schedInstId = instanceIdGenerator.generateInstanceId();
                }
            } catch (Exception e) {
                getLog().error("Couldn't generate instance Id!", e);
                throw new IllegalStateException("Cannot run without an instance id.");
            }
        }
        if (js.getClass().getName().startsWith("org.terracotta.quartz")) {
            try {
                String uuid = (String) js.getClass().getMethod("getUUID").invoke(js);
                if (schedInstId.equals(DEFAULT_INSTANCE_ID)) {
                    schedInstId = "TERRACOTTA_CLUSTERED,node=" + uuid;
                    if (jmxObjectName == null) {
                        jmxObjectName = QuartzSchedulerResources.generateJMXObjectName(schedName, schedInstId);
                    }
                } else if (jmxObjectName == null) {
                    jmxObjectName = QuartzSchedulerResources.generateJMXObjectName(schedName, schedInstId + ",node=" + uuid);
                }
            } catch (Exception e) {
                throw new RuntimeException("Problem obtaining node id from TerracottaJobStore.", e);
            }
            if (null == cfg.getStringProperty(PROP_SCHED_JMX_EXPORT)) {
                jmxExport = true;
            }
        }
        if (js instanceof JobStoreSupport) {
            JobStoreSupport jjs = (JobStoreSupport) js;
            jjs.setDbRetryInterval(dbFailureRetry);
            if (threadsInheritInitalizersClassLoader)
                jjs.setThreadsInheritInitializersClassLoadContext(threadsInheritInitalizersClassLoader);
            jjs.setThreadExecutor(threadExecutor);
        }
        QuartzSchedulerResources rsrcs = new QuartzSchedulerResources();
        rsrcs.setName(schedName);
        rsrcs.setThreadName(threadName);
        rsrcs.setInstanceId(schedInstId);
        rsrcs.setJobRunShellFactory(jrsf);
        rsrcs.setMakeSchedulerThreadDaemon(makeSchedulerThreadDaemon);
        rsrcs.setThreadsInheritInitializersClassLoadContext(threadsInheritInitalizersClassLoader);
        rsrcs.setBatchTimeWindow(batchTimeWindow);
        rsrcs.setMaxBatchSize(maxBatchSize);
        rsrcs.setInterruptJobsOnShutdown(interruptJobsOnShutdown);
        rsrcs.setInterruptJobsOnShutdownWithWait(interruptJobsOnShutdownWithWait);
        rsrcs.setJMXExport(jmxExport);
        rsrcs.setJMXObjectName(jmxObjectName);
        if (managementRESTServiceEnabled) {
            ManagementRESTServiceConfiguration managementRESTServiceConfiguration = new ManagementRESTServiceConfiguration();
            managementRESTServiceConfiguration.setBind(managementRESTServiceHostAndPort);
            managementRESTServiceConfiguration.setEnabled(managementRESTServiceEnabled);
            rsrcs.setManagementRESTServiceConfiguration(managementRESTServiceConfiguration);
        }
        if (rmiExport) {
            rsrcs.setRMIRegistryHost(rmiHost);
            rsrcs.setRMIRegistryPort(rmiPort);
            rsrcs.setRMIServerPort(rmiServerPort);
            rsrcs.setRMICreateRegistryStrategy(rmiCreateRegistry);
            rsrcs.setRMIBindName(rmiBindName);
        }
        SchedulerDetailsSetter.setDetails(tp, schedName, schedInstId);
        rsrcs.setThreadExecutor(threadExecutor);
        threadExecutor.initialize();
        rsrcs.setThreadPool(tp);
        if (tp instanceof SimpleThreadPool) {
            if (threadsInheritInitalizersClassLoader)
                ((SimpleThreadPool) tp).setThreadsInheritContextClassLoaderOfInitializingThread(threadsInheritInitalizersClassLoader);
        }
        tp.initialize();
        tpInited = true;
        rsrcs.setJobStore(js);
        // add plugins
        for (int i = 0; i < plugins.length; i++) {
            rsrcs.addSchedulerPlugin(plugins[i]);
        }
        qs = new QuartzScheduler(rsrcs, idleWaitTime, dbFailureRetry);
        qsInited = true;
        // Create Scheduler ref...
        Scheduler scheduler = instantiate(rsrcs, qs);
        // set job factory if specified
        if (jobFactory != null) {
            qs.setJobFactory(jobFactory);
        }
        // Initialize plugins now that we have a Scheduler instance.
        for (int i = 0; i < plugins.length; i++) {
            plugins[i].initialize(pluginNames[i], scheduler, loadHelper);
        }
        // add listeners
        for (int i = 0; i < jobListeners.length; i++) {
            qs.getListenerManager().addJobListener(jobListeners[i], EverythingMatcher.allJobs());
        }
        for (int i = 0; i < triggerListeners.length; i++) {
            qs.getListenerManager().addTriggerListener(triggerListeners[i], EverythingMatcher.allTriggers());
        }
        // set scheduler context data...
        for (Object key : schedCtxtProps.keySet()) {
            String val = schedCtxtProps.getProperty((String) key);
            scheduler.getContext().put((String) key, val);
        }
        // fire up job store, and runshell factory
        js.setInstanceId(schedInstId);
        js.setInstanceName(schedName);
        js.setThreadPoolSize(tp.getPoolSize());
        js.initialize(loadHelper, qs.getSchedulerSignaler());
        jrsf.initialize(scheduler);
        qs.initialize();
        getLog().info("Quartz scheduler '" + scheduler.getSchedulerName() + "' initialized from " + propSrc);
        getLog().info("Quartz scheduler version: " + qs.getVersion());
        // prevents the repository from being garbage collected
        qs.addNoGCObject(schedRep);
        // prevents the db manager from being garbage collected
        if (dbMgr != null) {
            qs.addNoGCObject(dbMgr);
        }
        schedRep.bind(scheduler);
        return scheduler;
    } catch (SchedulerException e) {
        shutdownFromInstantiateException(tp, qs, tpInited, qsInited);
        throw e;
    } catch (RuntimeException re) {
        shutdownFromInstantiateException(tp, qs, tpInited, qsInited);
        throw re;
    } catch (Error re) {
        shutdownFromInstantiateException(tp, qs, tpInited, qsInited);
        throw re;
    }
}
Also used : SchedulerException(org.quartz.SchedulerException) JNDIConnectionProvider(org.quartz.utils.JNDIConnectionProvider) PoolingConnectionProvider(org.quartz.utils.PoolingConnectionProvider) ConnectionProvider(org.quartz.utils.ConnectionProvider) JobFactory(org.quartz.spi.JobFactory) JTAAnnotationAwareJobRunShellFactory(org.quartz.ee.jta.JTAAnnotationAwareJobRunShellFactory) ThreadExecutor(org.quartz.spi.ThreadExecutor) JobRunShellFactory(org.quartz.core.JobRunShellFactory) JTAJobRunShellFactory(org.quartz.ee.jta.JTAJobRunShellFactory) JTAAnnotationAwareJobRunShellFactory(org.quartz.ee.jta.JTAAnnotationAwareJobRunShellFactory) SchedulerPlugin(org.quartz.spi.SchedulerPlugin) JobStoreSupport(org.quartz.impl.jdbcjobstore.JobStoreSupport) JobStore(org.quartz.spi.JobStore) RAMJobStore(org.quartz.simpl.RAMJobStore) ClassLoadHelper(org.quartz.spi.ClassLoadHelper) DBConnectionManager(org.quartz.utils.DBConnectionManager) RAMJobStore(org.quartz.simpl.RAMJobStore) Method(java.lang.reflect.Method) QuartzSchedulerResources(org.quartz.core.QuartzSchedulerResources) SchedulerConfigException(org.quartz.SchedulerConfigException) PropertiesParser(org.quartz.utils.PropertiesParser) PoolingConnectionProvider(org.quartz.utils.PoolingConnectionProvider) ManagementRESTServiceConfiguration(org.quartz.management.ManagementRESTServiceConfiguration) Scheduler(org.quartz.Scheduler) QuartzScheduler(org.quartz.core.QuartzScheduler) SimpleThreadPool(org.quartz.simpl.SimpleThreadPool) ThreadPool(org.quartz.spi.ThreadPool) QuartzScheduler(org.quartz.core.QuartzScheduler) Semaphore(org.quartz.impl.jdbcjobstore.Semaphore) Properties(java.util.Properties) JobListener(org.quartz.JobListener) JNDIConnectionProvider(org.quartz.utils.JNDIConnectionProvider) InstanceIdGenerator(org.quartz.spi.InstanceIdGenerator) JTAJobRunShellFactory(org.quartz.ee.jta.JTAJobRunShellFactory) SimpleThreadPool(org.quartz.simpl.SimpleThreadPool) TriggerListener(org.quartz.TriggerListener) SchedulerConfigException(org.quartz.SchedulerConfigException) IntrospectionException(java.beans.IntrospectionException) AccessControlException(java.security.AccessControlException) SchedulerException(org.quartz.SchedulerException) IOException(java.io.IOException) TablePrefixAware(org.quartz.impl.jdbcjobstore.TablePrefixAware)

Aggregations

SchedulerConfigException (org.quartz.SchedulerConfigException)2 ConnectionProvider (org.quartz.utils.ConnectionProvider)2 IntrospectionException (java.beans.IntrospectionException)1 IOException (java.io.IOException)1 Method (java.lang.reflect.Method)1 AccessControlException (java.security.AccessControlException)1 Connection (java.sql.Connection)1 DatabaseMetaData (java.sql.DatabaseMetaData)1 SQLException (java.sql.SQLException)1 Properties (java.util.Properties)1 DataSource (javax.sql.DataSource)1 JobListener (org.quartz.JobListener)1 Scheduler (org.quartz.Scheduler)1 SchedulerException (org.quartz.SchedulerException)1 TriggerListener (org.quartz.TriggerListener)1 JobRunShellFactory (org.quartz.core.JobRunShellFactory)1 QuartzScheduler (org.quartz.core.QuartzScheduler)1 QuartzSchedulerResources (org.quartz.core.QuartzSchedulerResources)1 JTAAnnotationAwareJobRunShellFactory (org.quartz.ee.jta.JTAAnnotationAwareJobRunShellFactory)1 JTAJobRunShellFactory (org.quartz.ee.jta.JTAJobRunShellFactory)1