spring boot quartz not starting in clustered mode - spring-boot

My spring boot application always starts quartz in non clustered mode.
Below is my configurations:
spring.quartz:
job-store-type: jdbc
jdbc:
initialize-schema: never
properties:
org:
quartz:
scheduler:
instanceId: AUTO
instanceName: myQuartzScheduler
job-store:
dataSource: quartzDataSource
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
useProperties: false
tablePrefix: QRTZ_
misfireThreshold: 60000
clusterCheckinInterval: 5000
isClustered: true
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
added dependency
spring-boot-starter-quartz
have quartz job and trigger in place. Application starts and the job gets fired as per the cron. but quartz always starts in non clustered mode:
2022-07-29 11:10:09.810 INFO 86257 --- [ main] o.s.s.quartz.LocalDataSourceJobStore : JobStoreCMT initialized.
2022-07-29 11:10:09.810 INFO 86257 --- [ main] org.quartz.core.QuartzScheduler : Scheduler meta-data: Quartz Scheduler (v2.3.2) 'myQuartzScheduler' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.springframework.scheduling.quartz.LocalDataSourceJobStore' - which supports persistence. and is not clustered.
What did I miss folks? I need to start quartz in clustered mode. Any help, appreciated. Thank you.

You have probably followed this article on how to build the clustered job scheduler.
In your case however you have used the
job-store:
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
The property however org.quartz.jobStore.isClustered: true that you later use, does not exist in common spring boot properties. It is a specific property, that is used from a specific JobStore, namely the org.quartz.impl.jdbcjobstore.JobStoreTX
Referenced doc
If you don't have any further conflicts in your properties, just changing into the following should fix the issue.
job-store:
class: org.quartz.impl.jdbcjobstore.JobStoreTX

The hint from #Panagiotis Bougioukos helped.
I had to change the configuration job-store: to jobStore: then the class class: org.quartz.impl.jdbcjobstore.JobStoreTX was honoured and Quartz started in clustered mode.
Finally
spring.quartz:
job-store-type: jdbc
jdbc:
initialize-schema: never
properties:
org:
quartz:
scheduler:
instanceId: AUTO
instanceName: myQuartzScheduler
jobStore:
dataSource: quartzDataSource
.
.
dataSource.quartzDataSource:
driver: com.mysql.cj.jdbc.Driver
URL: jdbc:mysql://${database.host:localhost}:${database.port:3306}/${database.name:mySchema}
user: myUser
password: ******
provider: hikaricp
and defining the quartzDataSource helped.

Related

How can I override the JPA properties for multiple datasources for Integration tests?

I have sucessfully configured two datasources for two different databases and schemas in my Spring Boot application. Now, for the integration tests I want to use an embedded database (HSQL) and execute the tests there. I tried overriding the properties using the following file (/src/test/resources/application-test.properties)
eot.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
eot.datasource.username=sa
eot.datasource.password=sa
eot.datasource.url=jdbc:hsqldb:mem:test;DB_CLOSE_DELAY=-1
eot.datasource.hikari.pool-name=ptest-eot
eot.datasource.jpa.show-sql=true
eot.datasource.jpa.generate-ddl=true
eot.datasource.jpa.database-platform=org.hibernate.dialect.HSQLDialect
eot.datasource.jpa.properties.hibernate.ddl-auto=create
eot.datasource.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
info.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
info.datasource.username=sa
info.datasource.password=sa
info.datasource.url=jdbc:hsqldb:mem:test;DB_CLOSE_DELAY=-1
info.datasource.hikari.pool-name=ptest-info
info.datasource.jpa.show-sql=true
info.datasource.jpa.generate-ddl=true
info.datasource.jpa.database-platform=org.hibernate.dialect.HSQLDialect
info.datasource.jpa.properties.hibernate.ddl-auto=create
info.datasource.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
In the log I can see it picks up some of the properties. In my application.yml the pool's name is 'eot-pool' and when I run the tests it shows correctly as 'ptest-eot'.
2022-05-27 17:09:03.855 INFO 6592 --- [ Test worker] mx.com.gnp.crm.adfe.EotJpaConfiguration : org.springframework.boot.autoconfigure.jdbc.DataSourceProperties#18a1fd92
2022-05-27 17:09:04.039 INFO 6592 --- [ Test worker] com.zaxxer.hikari.HikariDataSource : ptest-eot - Starting...
2022-05-27 17:09:04.845 INFO 6592 --- [ Test worker] com.zaxxer.hikari.pool.PoolBase : ptest-eot - Driver does not support get/set network timeout for connections. (característica no soportada)
2022-05-27 17:09:04.851 INFO 6592 --- [ Test worker] com.zaxxer.hikari.HikariDataSource : ptest-eot - Start completed.
But it's not overriding the JPA properties. It's not creating the schemas, tables, nor printing the SQL statements to the log.
I tried removing the 'properties' part. Using for example:
info.datasource.jpa.show-sql=true
info.datasource.jpa.hibernate.ddl-auto=create
info.datasource.jpa.hibernate.dialect=org.hibernate.dialect.HSQLDialect
But the JPA properties aren't being replaced.
When I run the tests, the log shows the wrong dialect (from the main application.yml file).
HHH000400: Using dialect: org.hibernate.dialect.DB2400Dialect
And when the tests runs:
SQL Error: -5501, SQLState: 42501
Because the schema and the table don't exist.
How can I override the JPA properties for integration tests when I have multiple datasources?
It seems you have a general application.yml file and a specific application-test.properties file for the test environment. I'm not sure if you can mix those file extensions, probably not. Either you choose to use .yml or .properties for both. Try to change the file name to application-test.yml. Also, to activate this specific test environment it's necessary to put this config in application.yml:
spring:
profiles:
active:test

Failed to determine suitable jdbc url when deploy on gitlab

When I run the application locally, it works.
When I deploy the master branch in gitlabs's CI/CD pipeline it works too.
But when I run the deploy to other branch it launch an error:
APPLICATION FAILED TO START
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine suitable jdbc url
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (the profiles stag are currently active).
My application.yml:
datasource:
driver-class-name: org.postgresql.Driver
url: ${POSTGRES_URL}
username: ${POSTGRES_USER}
password: ${POSTGRES_PASS}
hikari:
connectionTimeout: 20000
idleTimeout: 20000
maxLifetime: 60000
maximum-pool-size: 10
jpa:
hibernate:
show-sql: true
ddl-auto: validate
properties:
hibernate:
globally_quoted_identifiers: true
dialect: org.hibernate.dialect.PostgreSQL10Dialect
show_sql: true
format_sql: true
database-platform: org.hibernate.dialect.PostgreSQL10Dialect

Configuring application using application.yaml instead of application.properties

I have a small Quarkus 1.1.0.Final Web application (using Java 1.8). I'm trying to use a YAML file to configure the application (instead of the usual application.properties) but there is no way the application comes up. I'm always getting this not-so-useful error message(s):
13:53:32,494 ERROR [io.qua.dev.DevModeMain] Failed to start Quarkus: java.lang.RuntimeException: io.quarkus.builder.ChainBuildException: No producers for required item class io.quarkus.deployment.builditem.BuildTimeRunTimeFixedConfigurationBuildItem
at io.quarkus.runner.RuntimeRunner.run(RuntimeRunner.java:180)
at io.quarkus.dev.DevModeMain.doStart(DevModeMain.java:177)
at io.quarkus.dev.DevModeMain.start(DevModeMain.java:95)
at io.quarkus.dev.DevModeMain.main(DevModeMain.java:66)
Caused by: io.quarkus.builder.ChainBuildException: No producers for required item class io.quarkus.deployment.builditem.BuildTimeRunTimeFixedConfigurationBuildItem
at io.quarkus.builder.BuildChainBuilder.build(BuildChainBuilder.java:240)
at io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:112)
at io.quarkus.runner.RuntimeRunner.run(RuntimeRunner.java:113)
... 3 more
13:53:32,519 INFO [io.qua.dev.DevModeMain] Attempting to start hot replacement endpoint to recover from previous Quarkus startup failure
13:53:32,532 ERROR [io.qua.dev.DevModeMain] Failed to start quarkus: java.lang.IllegalArgumentException: workerPoolSize must be > 0
at io.vertx.core.VertxOptions.setWorkerPoolSize(VertxOptions.java:275)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder.convertToVertxOptions(VertxCoreRecorder.java:151)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder.initializeWeb(VertxCoreRecorder.java:104)
at io.quarkus.vertx.http.runtime.VertxHttpRecorder.startServerAfterFailedStart(VertxHttpRecorder.java:115)
at io.quarkus.vertx.http.deployment.devmode.VertxHotReplacementSetup.handleFailedInitialStart(VertxHotReplacementSetup.java:30)
at io.quarkus.dev.RuntimeUpdatesProcessor.startupFailed(RuntimeUpdatesProcessor.java:449)
at io.quarkus.dev.DevModeMain.doStart(DevModeMain.java:191)
at io.quarkus.dev.DevModeMain.start(DevModeMain.java:95)
at io.quarkus.dev.DevModeMain.main(DevModeMain.java:66)
This is my YAML file:
#
# https://quarkus.io/guides/all-config
# https://quarkus.io/guides/config#overriding-properties-at-runtime
quarkus:
datasource:
driver: org.postgresql.Driver
flyway:
migrate-at-start: true
health:
extensions:
enabled: true
hibernate-orm:
dialect: org.hibernate.dialect.PostgreSQL10Dialect
http:
port: 8080
log: # ALL > FINEST > FINER > FINE > CONFIG > INFO > WARNING > SEVERE > OFF
console:
async: true
color: true
enable: true
format: "%d{yyyy-MM-dd HH:mm:ss,SSS} |- %-5p in %c:%L{3.} [%t] - %s%e%n"
level: WARNING
resteasy:
path: /api
smallrye-openapi:
path: /open-api
swagger-ui:
always-include: true
path: /swagger-ui
"%dev":
quarkus:
datasource:
password: postgres
url: jdbc:postgresql://localhost:5432/quarkus_web
username: postgres
flyway:
clean-at-start: true
hibernate-orm:
log:
sql: true
statistics: true
log:
category:
"io.quarkus.arc.processor":
level: OFF
"io.quarkus":
level: INFO
"org.acme":
level: CONFIG
"%prod":
quarkus:
datasource:
password: postgres
url: jdbc:postgresql://localhost:5432/quarkus_web
username: postgres
flyway:
clean-at-start: false
hibernate-orm:
database:
generation: none
sql-load-script: no-file
"%test":
quarkus:
datasource:
password: postgres
url: jdbc:postgresql://localhost:5432/quarkus_web
username: postgres
flyway:
clean-at-start: true
log:
category:
"io.quarkus":
level: WARNING
"org.acme":
level: WARNING
Anyone using this approach already and succeeded? I'm including io.quarkus:quarkus-config-yaml:1.1.0.Final.
One thing that I've noticed is that I can't separate the profiles using --- as I do with Spring Boot. I think I should file an issue for this :thinking_face:
It certainly looks like a bug, maybe even 2 as the second error message doesn't look like something I would expect considering your configuration file.
Could you create a bug in our tracker: https://github.com/quarkusio/quarkus/issues/new?assignees=&labels=bug&template=bug_report.md&title= ?
It would be nice if you could provide a reproducer. AFAICS, Quarkus doesn't start at all so probably your pom.xml with the various extensions you use and your configuration file should be enough to reproduce the issue.
Turns out this was not an issue. I just had an old Gradle config; some things changed with the Gradle plugin with version 1.1.0.Final and I just didn't have those.

Spring Boot Test seems to be creating H2 Test DB different than what I would expect

So, I have a Test annotated with #DataJpaTest and #RunWith(SpringRunner.class), and an application.yml under /src/test/resources with this block (yes, indenting should be fine):
spring:
datasource:
url: jdbc:h2:mem:foobar;MODE=Mysql;MVCC=FALSE;
username: sa
password:
driver-class-name: org.h2.Driver
When I start the Test, I unexpectedly get these lines in the log:
2019-10-23 17:11:08.311 INFO 13468 --- [ main] beddedDataSourceBeanFactoryPostProcessor : Replacing 'dataSource' DataSource bean with embedded version
2019-10-23 17:11:08.801 INFO 13468 --- [ main] o.s.j.d.e.EmbeddedDatabaseFactory : Starting embedded database: url='jdbc:h2:mem:7855270f-61b7-4f37-8796-cbfeb8ad42ea;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
In particular this: Starting embedded database: url='jdbc:h2:mem:7855270f-61b7-4f37-8796-cbfeb8ad42ea;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false
Why is Spring boot starting a DB with a UUID-Generated DB and not taking the settings from spring.datasource.url?
The "productive" app takes the datasource settings fine from the file in /src/main/resources with same syntax without issues...
From the documentation of #DataJpaTest you can see that:
#DataJpaTest uses an embedded in-memory
database (replacing any explicit or usually auto-configured
DataSource). The #AutoConfigureTestDatabase annotation can be used to
override these settings.
So #DataJpaTest annotated with #AutoConfigureTestDatabase that causes TestDatabaseAutoConfiguration to create embedded datasource with hard-coded generateUniqueName(true):
TestDatabaseAutoConfiguration.java :
EmbeddedDatabase getEmbeddedDatabase() {
...
return new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(connection.getType())
.build();
}
I think they do this to prevent DB name collisions and state mix between test runs.

Spring Quartz integration Quartz getting initialized twice

I have been working on integration our current project with Jersey, the webapplication uses Spring for IOC and Quartz scheduling. But post getting the configuration working I notice the following in the log files during startup:
2014-08-15 05:43:10,830 INFO org.quartz.core.SchedulerSignalerImpl.<init>:63 - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2014-08-15 05:43:10,834 INFO org.quartz.core.QuartzScheduler.<init>:215 - Quartz Scheduler v.1.6.5 created.
2014-08-15 05:43:10,838 INFO org.quartz.simpl.RAMJobStore.initialize:141 - RAMJobStore initialized.
2014-08-15 05:43:10,840 INFO org.quartz.impl.StdSchedulerFactory.instantiate:1229 - Quartz scheduler 'syncSchContext' initialized from an externally provided properties instance.
2014-08-15 05:43:10,841 INFO org.quartz.impl.StdSchedulerFactory.instantiate:1233 - Quartz scheduler version: 1.6.5
2014-08-15 05:43:10,848 INFO org.quartz.core.QuartzScheduler.setJobFactory:2094 - JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory#210e5887
2014-08-15 05:43:10,995 INFO org.quartz.core.SchedulerSignalerImpl.<init>:63 - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2014-08-15 05:43:10,996 INFO org.quartz.core.QuartzScheduler.<init>:215 - Quartz Scheduler v.1.6.5 created.
2014-08-15 05:43:10,997 INFO org.quartz.simpl.RAMJobStore.initialize:141 - RAMJobStore initialized.
2014-08-15 05:43:10,997 INFO org.quartz.impl.StdSchedulerFactory.instantiate:1229 - Quartz scheduler 'org.springframework.scheduling.quartz.SchedulerFactoryBean#0' initialized from an externally provided properties instance.
2014-08-15 05:43:10,997 INFO org.quartz.impl.StdSchedulerFactory.instantiate:1233 - Quartz scheduler version: 1.6.5
2014-08-15 05:43:10,998 INFO org.quartz.core.QuartzScheduler.setJobFactory:2094 - JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory#cd79d78
2014-08-15 05:43:11,795 INFO org.quartz.core.QuartzScheduler.start:461 - Scheduler syncSchContext_$_NON_CLUSTERED started.
2014-08-15 05:43:11,796 INFO org.quartz.core.QuartzScheduler.start:461 - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED started.
What might be causing this initialization to happen twice?
The most common situation that would cause the scheduler to run twice is if the bean that is bean scheduled in included in multiple contexts.
Make sure that the scheduled beans belong only to the root application context.

Resources