Quartz Scheduler create schedulerFactoryBean Beans without quartz.properties - java

I have running quartz scheduler with inside my spring app.
right now, i'm using quartz.properties to contain any properties value and use it to create schedulerFactoryBean Bean and it works fine.
this is my QuartzConfiguration..
#Configuration
public class QuartzConfiguration {
public static final String CONTEXT_KEY = "applicationContext";
//#Autowired
//private DataSource dataSource;
#Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
scheduler.setApplicationContextSchedulerContextKey(CONTEXT_KEY);
scheduler.setConfigLocation(new ClassPathResource("config/quartz.properties"));
//scheduler.setDataSource(dataSource);
//scheduler.setAutoStartup(true);
scheduler.setWaitForJobsToCompleteOnShutdown(true);
return scheduler;
}
}
My quartz.properties :
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties=false
org.quartz.jobStore.dataSource=myDS
org.quartz.dataSource.myDS.driver =oracle.jdbc.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:#example:1521:db
org.quartz.dataSource.myDS.user = user
org.quartz.dataSource.myDS.password = password
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery = select 1 from dual
org.quartz.jobStore.isClustered=false
org.quartz.jobStore.tablePrefix = DPPA.QUARTZ_
org.quartz.threadPool.threadCount=1
org.quartz.scheduler.skipUpdateCheck=true
org.quartz.plugin.jobHistory.class=id.co.fifgroup.dpa.batch.BatchHistoryListener
i want to create schedulerFactoryBean without any quartz.properties, because my client dont want to change any database connection inside the war archieve.
is it possible to create schedulerFactoryBean without any quartz.properties ?

You can configure it without properties file in this way;
Properties p = new Properties();
p.put("org.quartz.scheduler.instanceName", "Scheduler_test");
p.put("org.quartz.threadPool.threadCount", 2);
...
StdSchedulerFactory factory = new StdSchedulerFactory(p);

Related

Quartz Scheduler NOT STARTED

I am creating a spring boot application that is using Quartz this is my quartz.yaml file
org:
quartz:
dataSource:
mySql:
maxIdleTime: '60'
idleConnectionValidationSeconds: '50'
password: test2
user: test2
URL: jdbc:mysql://localhost:3306/schedules?useSSL=false
driver: com.mysql.jdbc.Driver
maxConnections: '10'
validationQuery: select 0 from dual
plugin:
jobHistory:
class: org.quartz.plugins.history.LoggingJobHistoryPlugin
jobToBeFiredMessage: 'Job [{1}.{0}] to be fired by trigger [{4}.{3}], re-fire:
{7}'
jobFailedMessage: 'Job [{1}.{0}] execution failed with exception: {8}'
jobWasVetoedMessage: 'Job [{1}.{0}] was vetoed. It was to be fired by trigger
[{4}.{3}] at: {2, date, dd-MM-yyyy HH:mm:ss.SSS}'
jobSuccessMessage: 'Job [{1}.{0}] execution complete and reports: {8}'
triggerHistory:
class: org.quartz.plugins.history.LoggingTriggerHistoryPlugin
triggerFiredMessage: 'Trigger [{1}.{0}] fired job [{6}.{5}] scheduled at:
{2, date, dd-MM-yyyy HH:mm:ss.SSS}, next scheduled at: {3, date, dd-MM-yyyy
HH:mm:ss.SSS}'
triggerCompleteMessage: 'Trigger [{1}.{0}] completed firing job [{6}.{5}]
with resulting trigger instruction code: {9}. Next scheduled at: {3, date,
dd-MM-yyyy HH:mm:ss.SSS}'
triggerMisfiredMessage: 'Trigger [{1}.{0}] misfired job [{6}.{5}]. Should
have fired at: {3, date, dd-MM-yyyy HH:mm:ss.SSS}'
jobStore:
maxMisfiresToHandleAtATime: '10'
dataSource: mySql
isClustered: 'false'
class: org.quartz.impl.jdbcjobstore.JobStoreTX
useProperties: 'true'
misfireThreshold: '60000'
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
threadPool:
threadPriority: '5'
class: org.quartz.simpl.SimpleThreadPool
threadCount: '4'
scheduler:
instanceId: AUTO
instanceName: SampleJobScheduler
idleWaitTime: '10000'
I am trying to use SQL database but its uses ram. This is the error I am getting
Scheduler class: 'org.quartz.core.QuartzScheduler' - running
locally. NOT STARTED. Currently in standby mode. Number of jobs
executed: 0 Using thread pool 'org.quartz.simpl.SimpleThreadPool' -
with 10 threads. Using job-store 'org.quartz.simpl.RAMJobStore' -
which does not support persistence. and is not clustered.
This is my Configuration
#Configuration
public class Config {
#Value("${library.file-path.quartz}")
Resource quartsPath;
#Autowired private ApplicationContext applicationContext;
#Bean
public SchedulerFactoryBean scheduler(JobFactory factory) throws IOException {
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
schedulerFactory.setQuartzProperties(quartzProperties());
schedulerFactory.setJobFactory(factory);
return schedulerFactory;
}
#Bean
public SpringBeanJobFactory springBeanJobFactory() {
AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(quartsPath);
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
}
I got it working setting the datasource in SchedulerFactoryBean.
dataSource is the DataSource used by the application and inyected by Spring in this configuration class:
#Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setJobFactory(springBeanJobFactory());
factory.setQuartzProperties(quartzProperties());
factory.setDataSource(dataSource);
return factory;
}

Connecting quartz datasource to spring boot bean

I have set up a connection to our database, using a bean in spring boot. This all works correctly in our normal application.
#Bean(name="MoliDBConfig")
#Primary
public DataSource dataSource() throws SQLException {
I would like to connect to the same datasource from quartz, but am getting a JNDI error. (As an aside it is worth noting that I have managed to connect to a datasource from quartz by manually providing the config details. See the commented out code in quartz.properties below.)
2019-03-19T10:51:52.342+00:00 [APP/PROC/WEB/0] [OUT] ERROR 2019-03-19 10:51:52.333 - o.q.u.JNDIConnectionProvider 126 Error looking up datasource: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial| at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662) ~[?:1.8.0_202]| at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313) ~[?:1.8.0_202]| at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350) ~[?:1.8.0_202]| at javax.naming.InitialContext.lookup(InitialContext.java:417) ~[?:1.8.0_202]| at org.quartz.utils.JNDIConnectionProvider.init(JNDIConnectionProvider.java:124) [quartz-2.3.0.jar!/:?]| at org.quartz.utils.JNDIConnectionProvider.(JNDIConnectionProvider.java:102) [quartz-2.3.0.jar!/:?]| at org.quartz.impl.StdSchedulerFactory.instantiate(StdSchedulerFactory.java:995) [quartz-2.3.0.jar!/:?]| at org.quartz.impl.StdSchedulerFactory.getScheduler(StdSchedulerFactory.java:1559) [quartz-2.3.0.jar!/:?]| at com.xxx.d3.moli.schedule.QrtzScheduler.scheduler(QrtzScheduler.java:52) [classes/:?]| at com.xxx.d3.moli.schedule.QrtzScheduler$$EnhancerBySpringCGLIB$$aa50aa7b.CGLIB$scheduler$1() [classes/:?]| at com.xxx.d3.moli.schedule.QrtzScheduler$$EnhancerBySpringCGLIB$$aa50aa7b$$FastClassBySpringCGLIB$$374ea1c1.invoke() [classes/:?]| at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) [spring-core-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]| at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) [spring-context-4.3.22.RELEASE.jar!/:4.3.22.RELEASE]| at com.xxx.d3.moli.schedule.QrtzScheduler$$EnhancerBySpringCGLIB$$aa50aa7b.scheduler() [classes/:?]
quartz.properties
# Configure Main Scheduler Properties
org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
# thread-pool
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=2
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
# job-store
#org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.class = org.springframework.scheduling.quartz.LocalDataSourceJobStore
#org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.dataSource = managedTXDS
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
# Configure Datasources
org.quartz.dataSource.managedTXDS.jndiURL=java:comp/env/jdbc/MoliDBConfig
org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:#ldap://oid.xxx.com:389/odsod012,cn=OracleContext,dc=xxx,dc=com
org.quartz.dataSource.myDS.user = MOLI_QRTZ_SCHED
org.quartz.dataSource.myDS.password = MOLI_QRTZ_SCHED
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual
# A different classloader is needed to work with Spring Boot dev mode,
# see https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html#using-boot-devtools-known-restart-limitations
# and https://github.com/quartz-scheduler/quartz/issues/221
org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.ThreadContextClassLoadHelper
And my quartz config file
#Configuration
#Profile({"oracle-cloud","mysql-cloud"})
public class QrtzScheduler {
private static final Logger LOGGER = LogManager.getLogger(QrtzScheduler.class);
#Autowired
private ApplicationContext applicationContext;
#PostConstruct
public void init() {
LOGGER.info("Hello world from Quartz...");
}
#Bean
public SpringBeanJobFactory springBeanJobFactory() {
AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory();
LOGGER.debug("Configuring Job factory");
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
#Bean
public Scheduler scheduler(Trigger trigger, JobDetail job) throws SchedulerException, IOException {
StdSchedulerFactory factory = new StdSchedulerFactory();
factory.initialize(new ClassPathResource("quartz/quartz.properties").getInputStream());
LOGGER.debug("Getting a handle to the Scheduler");
Scheduler scheduler = factory.getScheduler();
scheduler.setJobFactory(springBeanJobFactory());
if (scheduler.checkExists(job.getKey())){
scheduler.deleteJob(job.getKey());
}
scheduler.scheduleJob(job, trigger);
LOGGER.debug("Starting Scheduler threads");
scheduler.start();
return scheduler;
}
#Bean
public JobDetail jobDetail() {
return JobBuilder.newJob()
.ofType(ScheduledJob.class)
.storeDurably()
.withIdentity(JobKey.jobKey("Qrtz_Job_Detail"))
.withDescription("Invoke Sample Job service...")
.build();
}
#Bean
public Trigger trigger(JobDetail job) {
int frequencyInMin = 5;
LOGGER.info("Configuring trigger to fire every {} minutes", frequencyInMin);
return TriggerBuilder.newTrigger().forJob(job)
.withIdentity(TriggerKey.triggerKey("Qrtz_Trigger"))
.withDescription("Sample trigger")
.withSchedule(simpleSchedule().withIntervalInMinutes(frequencyInMin).repeatForever())
.build();
}
}
What is wrong with my approach? (The documentation at quartz-scheduler.org all appears to be down) :-(
So I changed over to this:
#Configuration
#Profile({"oracle-cloud","mysql-cloud"})
public class QrtzScheduler {
private static final Logger LOGGER = LogManager.getLogger(QrtzScheduler.class);
#Autowired
private ApplicationContext applicationContext;
#Autowired
#Qualifier("MoliDBConfig")
private DataSource dataSource;
#Value("${app.repeatInterval}")
private int repeatInterval;
#Value("${org.quartz.scheduler.instanceName}")
private String instanceName;
#Value("${org.quartz.scheduler.instanceId}")
private String instanceId;
#Value("${org.quartz.threadPool.threadCount}")
private String threadCount;
#Value("${org.quartz.threadPool.class}")
private String threadClass;
#Value("${org.quartz.threadPool.threadPriority}")
private String threadPriority;
#Value("${org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread}")
private String threadsInheritContextClassLoaderOfInitializingThread;
#Value("${org.quartz.jobStore.class}")
private String jobStoreClass;
#Value("${org.quartz.jobStore.driverDelegateClass}")
private String jobStoreDriverDelegateClass;
#Value("${org.quartz.jobStore.useProperties}")
private String jobStoreUseProperties;
#Value("${org.quartz.jobStore.tablePrefix}")
private String jobStoreTablePrefix;
#Value("${org.quartz.jobStore.misfireThreshold}")
private String jobStoreMisfireThreshold;
#Value("${org.quartz.jobStore.isClustered}")
private String jobStoreIsClustered;
#Value("${org.quartz.jobStore.clusterCheckinInterval}")
private String jobStoreClusterCheckinInterval;
#Value("${org.quartz.scheduler.classLoadHelper.class}")
private String schedulerClassLoadHelperClass;
#PostConstruct
public void init() {
LOGGER.info("Hello world from Quartz...");
}
#Bean
public SpringBeanJobFactory jobFactory() {
AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory();
LOGGER.debug("Configuring Job factory");
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
#Bean
public SchedulerFactoryBean schedulerFactoryBean() {
LOGGER.debug("Configuring schedulerFactoryBean");
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setOverwriteExistingJobs(true);
factory.setJobFactory(jobFactory());
Properties quartzProperties = new Properties();
quartzProperties.setProperty("org.quartz.scheduler.instanceName",instanceName);
quartzProperties.setProperty("org.quartz.scheduler.instanceId",instanceId);
quartzProperties.setProperty("org.quartz.threadPool.threadCount",threadCount);
quartzProperties.setProperty("org.quartz.threadPool.class",threadClass);
quartzProperties.setProperty("org.quartz.threadPool.threadPriority",threadPriority);
quartzProperties.setProperty("org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread",threadsInheritContextClassLoaderOfInitializingThread);
quartzProperties.setProperty("org.quartz.jobStore.class",jobStoreClass);
quartzProperties.setProperty("org.quartz.jobStore.driverDelegateClass",jobStoreDriverDelegateClass);
quartzProperties.setProperty("org.quartz.jobStore.useProperties",jobStoreUseProperties);
quartzProperties.setProperty("org.quartz.jobStore.tablePrefix",jobStoreTablePrefix);
quartzProperties.setProperty("org.quartz.jobStore.misfireThreshold",jobStoreMisfireThreshold);
quartzProperties.setProperty("org.quartz.jobStore.isClustered",jobStoreIsClustered);
quartzProperties.setProperty("org.quartz.jobStore.clusterCheckinInterval",jobStoreClusterCheckinInterval);
quartzProperties.setProperty("org.quartz.scheduler.classLoadHelper.class",schedulerClassLoadHelperClass);
factory.setDataSource(dataSource);
factory.setQuartzProperties(quartzProperties);
factory.setTriggers(moliJobTrigger().getObject());
return factory;
}
#Bean(name = "moliJobTrigger")
public SimpleTriggerFactoryBean moliJobTrigger() {
long minute = 60000;
long repeatIntervalInMin = repeatInterval * minute;
LOGGER.debug("Configuring jobTrigger");
SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
factoryBean.setJobDetail(moliJobDetails().getObject());
factoryBean.setStartDelay(minute);
factoryBean.setRepeatInterval(repeatIntervalInMin);
factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
return factoryBean;
}
#Bean(name = "moliJobDetails")
public JobDetailFactoryBean moliJobDetails() {
LOGGER.debug("Configuring jobDetails");
JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
jobDetailFactoryBean.setJobClass(ScheduledAutomaticMonitoringJob.class);
jobDetailFactoryBean.setDescription("Moli_Quartz_Description");
jobDetailFactoryBean.setDurability(true);
jobDetailFactoryBean.setName("Moli_Quartz_Name");
return jobDetailFactoryBean;
}
}
application.yml
org:
quartz:
scheduler:
instanceName: MyClusteredScheduler
instanceId: AUTO
classLoadHelper:
class: org.quartz.simpl.ThreadContextClassLoadHelper
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
jobStore:
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
dataSource: app.dataSource
driverDelegateClass: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
useProperties: false
tablePrefix: COT_QRTZ_
misfireThreshold: 60000
isClustered: true
clusterCheckinInterval: 20000
Also needed this class:
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
/**
* Adds auto-wiring support to quartz jobs.
*/
public final class AutoWiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private AutowireCapableBeanFactory beanFactory;
public void setApplicationContext(ApplicationContext applicationContext) {
beanFactory = applicationContext.getAutowireCapableBeanFactory();
}
#Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}

Configure OracleDataSource programmatically in Spring Boot with a default schema

How to configure Oracle DataSource programmatically in Spring Boot with a default schema?
#Bean
public DataSource getDataSource() throws SQLException {
OracleDataSource d = new OracleDataSource();
d.setURL(Secrets.get("DB_URL"));
d.setUser(Secrets.get("DB_USER"));
d.setPassword(Secrets.get("DB_PASS"));
// d.setSchema(System.getenv("DB_SCHEMA")); ???
return d;
}
You can't change the schema in the OracleDataSource or using connection URL, you need to execute
ALTER SESSION SET CURRENT_SCHEMA=targetschema;
statement as explained in this answer. According to Connection Properties Recognized by Oracle JDBC Drivers there is no driver property for initial schema.
Full example:
#Bean
public DataSource getDataSource() throws SQLException {
OracleDataSource oracleDs = new OracleDataSource();
oracleDs.setURL(Secrets.get("DB_URL"));
oracleDs.setUser(Secrets.get("DB_USER"));
oracleDs.setPassword(Secrets.get("DB_PASS"));
// other Oracle related settings...
HikariDataSource hikariDs = new HikariDataSource();
hikariDs.setDataSource(oracleDs);
hikariDs.setConnectionInitSql("ALTER SESSION SET CURRENT_SCHEMA = MY_SCHEMA");
return hikariDs;
}
Try to add sql execution into datasources creation method
#Bean
public DataSource getDataSource() throws SQLException {
OracleDataSource d = new OracleDataSource();
d.setURL(Secrets.get("DB_URL"));
d.setUser(Secrets.get("DB_USER"));
d.setPassword(Secrets.get("DB_PASS"));
Resource initSchema = new ClassPathResource("scripts/schema-alter.sql");
DatabasePopulator databasePopulator = new ResourceDatabasePopulator(initSchema);
DatabasePopulatorUtils.execute(databasePopulator, dataSource);
return d;
}
In scripts/schema-alter.sql will be this code
ALTER SESSION SET CURRENT_SCHEMA=targetschema;
In Spring Boot 2 the wanted schema can be set in application.properties file with the following property:
spring.datasource.hikari.connection-init-sql=ALTER SESSION SET CURRENT_SCHEMA = MY_SCHEMA
HikariCP is the default connection pool in Spring Boot 2. To see all HikariCP settings (including "connectionInitSql") in you log file add also the following in application.properties:
logging.level.com.zaxxer.hikari=DEBUG

How to use JMX MBean for HikariCP in Spring boot application?

How to use JMX MBean for HikariCP in Spring boot application? I have a code like this:
#SpringBootApplication
public class App() { ... }
And other class:
#Configuration
public class DatabaseCfg() {
#Bean
#ManagedOperation
public DataSource ds (#Value("${hikari.proprerties}") String config) {
HikariConfig hikariConfig = new HikariConfig(config);
return new HikariDataSource(hikariConfig);
}
In Java Mission Control (or JMX Console) a saw only Datasource managed bean, not JMX MBean for HikariCP (link). Is it possible to add it too?
In Spring Boot 2.0+ you can set the register-mbeans property in your application.properties file
spring.datasource.hikari.register-mbeans = true
If you are using an earlier version of Spring Boot you will also have to set the datasource
spring.datasource.type = com.zaxxer.hikari.HikariDataSource
I believe on your hikariConfig you need to set a few additional settings. You need to register the MBeans and set a pool name on the configuration.
HikariConfig hiakriConfig = new HikariConfig(config);
hikariConfig.setRegisterMbeans(true);
kikariConfig.setPoolName("my-pool-1");
Yes you obviously could drive these through the properties as well. I'm not sure if you are including these in your properties file as they are not listed. Also please note you are spelling properties wrong (#Value("${ds.proprerties}") should probably should be (#Value("${ds.properties}") but I'm not sure how you actually have named variables and property files. You may want to double check if that is where you want to set all of the properties.
Try this. Exclude your Hiakri DataSource Bean from being registered by Spring.
#Resource
private ObjectProvider<MBeanExporter> mBeanExporter;
#Bean("dataSource")
public DataSource createDataSource() {
String url = hikariDataSourceConfig.getUrl();
String username = hikariDataSourceConfig.getUsername();
String password = hikariDataSourceConfig.getPassword();
long idleTimeoutInMilliSeconds =
hikariDataSourceConfig.getIdleTimeOutInMilliseconds();
long maxLifetimeInMilliseconds =
hikariDataSourceConfig.getMaxLifetimeInMilliseconds();
int maximumPoolSize = hikariDataSourceConfig.getMaximumPoolSize();
int minimumIdle = hikariDataSourceConfig.getMinimumIdle();
String poolName = "HikariDataSource";
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setRegisterMbeans(true);
hikariConfig.setJdbcUrl(url);
hikariConfig.setUsername(username);
hikariConfig.setPassword(password);
hikariConfig.setIdleTimeout(idleTimeoutInMilliSeconds);
hikariConfig.setMaxLifetime(maxLifetimeInMilliseconds);
hikariConfig.setMaximumPoolSize(maximumPoolSize);
hikariConfig.setMinimumIdle(minimumIdle);
hikariConfig.setPoolName(poolName);
HikariDataSource dataSource = new HikariDataSource(hikariConfig);
mBeanExporter
.ifUnique((exporter) -> exporter.addExcludedBean("dataSource"));
return dataSource;
}

How to programmatically use Spring's JdbcTemplate?

We use Spring's JdbcTemplate which is configured through Spring config as illustrated below. Is there a way to do this without injecting the data source? I'd like to just create the JdbcTemplate instance programmatically and "initalize" the datasource using TheOracleDS.
Our current config:
Java class
private JdbcTemplate jdbcTemplate;
#Resource(name = "myDataSource")
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
Spring config
<jee:jndi-lookup id="myDataSource" jndi-name="java:/TheOracleDS"/>
Oracle datasource config
<xa-datasource>
<jndi-name>TheOracleDS</jndi-name>
...
</xa-datasource>
Update: Reason I'm asking this is I'm not a total believer in dependency injection / having Spring manage beans..
Here's some sample code from a project I've written:
SimpleJdbcTemplate db;
DataSource dataSource = new SingleConnectionDataSource(System.getProperty(
"lingcog.db.connectstring"),
System.getProperty("lingcog.db.username"),
System.getProperty("lingcog.db.password"), false);
db = new SimpleJdbcTemplate(dataSource);
Maybe my code would be simpler if I used injection, but this is a good example of how to do this without using injection.
You can use an org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup object to find the data source you want by JDNI name.
DataSource dataSource = new JndiDataSourceLookup().getDataSource("java:/TheOracleDS")
SimpleJdbcTemplate db=new SimpleJdbcTemplate(dataSource);
Not sure why you want to do that but... you could lookup the JDNI datasource with Spring's JndiDataSourceLookup:
JndiDataSourceLookup lookup = new JndiDataSourceLookup();
lookup.setResourceRef(true); // if the lookup occurs in a J2EE container
DataSource ds = lookup.getDataSource(jndiName);
Or just perform a "manual" lookup using Sun's classes:
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("jdbc/AcmeDB");
Then, just pass the datasource reference to the JdbcTemplate constructor or call setDataSource(ds).
But, as I said, I have no idea why you don't want to use injection.
Just use a raw JNDI lookup:
public void setDataSourceName(String name) {
InitialContext ctx = new InitialContext();
jdbcTemplate = new JdbcTemplate((DataSource) ctx.lookup(name));
}

Categories

Resources