Reputation: 186
I am using Quartz & Spring Integration modules in spring boot application. After I added Spring Integration in pom, getting below exception. It was working before adding Spring Integration modules in pom. It looks like some conflicts between Quartz and Spring Integration. Please help.
Exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzScheduler' defined in class path resource [org/springframework/boot/autoconfigure/quartz/QuartzAutoConfiguration.class]: Invocation of init method failed; nested exception is org.quartz.SchedulerException: ThreadPool class 'org.springframework.scheduling.quartz.LocalTaskExecutorThreadPool' props could not be configured. [See nested exception: java.lang.NoSuchMethodException: No setter for property 'threadCount']
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1710) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:583) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:741) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
at com.xxx.t3.starter.Application.main(Application.java:31) [classes/:na]
Caused by: org.quartz.SchedulerException: ThreadPool class 'org.springframework.scheduling.quartz.LocalTaskExecutorThreadPool' props could not be configured.
at org.quartz.impl.StdSchedulerFactory.instantiate(StdSchedulerFactory.java:849) ~[quartz-2.3.0.jar:na]
at org.quartz.impl.StdSchedulerFactory.getScheduler(StdSchedulerFactory.java:1559) ~[quartz-2.3.0.jar:na]
at org.springframework.scheduling.quartz.SchedulerFactoryBean.createScheduler(SchedulerFactoryBean.java:636) ~[spring-context-support-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.scheduling.quartz.SchedulerFactoryBean.afterPropertiesSet(SchedulerFactoryBean.java:510) ~[spring-context-support-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1769) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
... 15 common frames omitted
Caused by: java.lang.NoSuchMethodException: No setter for property 'threadCount'
at org.quartz.impl.StdSchedulerFactory.setBeanProps(StdSchedulerFactory.java:1447) ~[quartz-2.3.0.jar:na]
at org.quartz.impl.StdSchedulerFactory.instantiate(StdSchedulerFactory.java:847) ~[quartz-2.3.0.jar:na]
... 20 common frames omitted
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxx</groupId>
<artifactId>etl</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-sftp</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>wlthint3client</artifactId>
<version>12.2.1.2</version>
<scope>system</scope>
<systemPath>C:/Oracle/products/mw_home/wlserver/server/lib/wlthint3client.jar</systemPath>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc</artifactId>
<version>7</version>
<scope>system</scope>
<systemPath>C:/Oracle/products/mw_home/oracle_common/modules/oracle.jdbc/ojdbc7.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sandp</groupId>
<artifactId>rsadecryptor</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>C:/DB/rsadecryptor.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
mail:
host: XXXXXXXXXX
port: 25
protocol: smtp
defaultEncoding: UTF-8
quartz:
jdbc:
initialize-schema: never
properties:
org:
quartz:
scheduler:
instanceId: AUTO
#instanceName: ETL
batchTriggerAcquisitionMaxCount: 25
skipUpdateCheck: true
threadPool:
threadCount: 50
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
tablePrefix: QRTZ_
useProperties: true
acquireTriggersWithinLock: true
email:
from: [email protected]
scheduler:
datasource:
url: jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXXXXXXXX)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XXXXXX)))
username: scheduler
password: XXXXXX
driver-class-name: oracle.jdbc.OracleDriver
t3:
datasource:
url: jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXXXXXXXXXXX)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XXXXXXXXXXXX)))
username: app
password: XXXXXXXXX
driver-class-name: oracle.jdbc.OracleDriver
Application.java
@ComponentScan("com.xxx.t3")
@IntegrationComponentScan
@EnableIntegration
@SpringBootApplication(exclude = { ActiveMQAutoConfiguration.class, JmxAutoConfiguration.class })
public class Application
{
public static void main(String[] args)
{
ApplicationContext context = SpringApplication.run(Application.class, args);
}
}
SchedulerConfig.java
@Configuration
public class SchedulerConfig
{
private DataSource dataSource;
private PlatformTransactionManager transactionManager;
@Autowired
public SchedulerConfig(@Qualifier("schedulerDataSource") DataSource dataSource, @Qualifier("schedulerTransactionManager") PlatformTransactionManager transactionManager)
{
this.dataSource = dataSource;
this.transactionManager = transactionManager;
}
@Bean
public SchedulerFactoryBeanCustomizer schedulerFactoryBeanCustomizer()
{
return bean ->
{
bean.setDataSource(dataSource);
bean.setTransactionManager(transactionManager);
bean.setSchedulerName("ETL");
};
}
}
SftpConfig.java
@ConfigurationProperties("sftp")
@Configuration
public class SftpConfig
{
private String host;
private int port;
private String user;
private String password;
private String remoteDirectory;
private String localDirectory;
@Bean
public SessionFactory<LsEntry> sftpSessionFactory()
{
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost(host);
factory.setPort(port);
factory.setUser(user);
factory.setPassword(password);
factory.setAllowUnknownKeys(true);
return new CachingSessionFactory<LsEntry>(factory);
}
@Bean
public SftpInboundFileSynchronizer sftpInboundFileSynchronizer()
{
SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
fileSynchronizer.setDeleteRemoteFiles(true);
fileSynchronizer.setRemoteDirectory(remoteDirectory);
return fileSynchronizer;
}
@Bean
@InboundChannelAdapter(channel = "fromSftpChannel", poller = @Poller(cron = "0/5 * * * * *"))
public MessageSource<File> sftpMessageSource()
{
SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(sftpInboundFileSynchronizer());
source.setAutoCreateLocalDirectory(true);
source.setLocalDirectory(new File(localDirectory));
return source;
}
@Bean
@ServiceActivator(inputChannel = "fromSftpChannel")
public MessageHandler resultFileHandler()
{
return new MessageHandler()
{
@Override
public void handleMessage(Message<?> message) throws MessagingException
{
System.out.println("File added - " + message.getPayload());
}
};
}
}
Upvotes: 2
Views: 6272
Reputation: 174739
Spring Integration auto-configures a TaskScheduler
, which is a TaskExecutor
.
I just looked at boot's auto configuration and if it finds exactly one task executor in the application context, it wires it into the quartz factory bean:
public QuartzAutoConfiguration(QuartzProperties properties,
ObjectProvider<List<SchedulerFactoryBeanCustomizer>> customizers,
ObjectProvider<Executor> taskExecutor, ObjectProvider<JobDetail[]> jobDetails,
ObjectProvider<Map<String, Calendar>> calendars,
ObjectProvider<Trigger[]> triggers, ApplicationContext applicationContext) {
this.properties = properties;
this.customizers = customizers.getIfAvailable();
this.taskExecutor = taskExecutor.getIfUnique();
this.jobDetails = jobDetails.getIfAvailable();
this.calendars = calendars.getIfAvailable();
this.triggers = triggers.getIfAvailable();
this.applicationContext = applicationContext;
}
and
if (this.taskExecutor != null) {
schedulerFactoryBean.setTaskExecutor(this.taskExecutor);
}
Then, the quartz factory bean configures a LocalTaskExecutorThreadPool
which doesn't have a thread count property.
You could add a second task executor so the getIfUnique()
call will return null.
I suggest you open a github issue against spring-boot to see if they can somehow avoid this issue.
EDIT
You should also be able to add bean.setTaskExecutor(null);
to your SchedulerFactoryBeanCustomizer
to revert the previous behavior.
Upvotes: 2