InstantiationError: org.quartz.JobDetail makes tomcat9 start failed in linux but fine in windows
InstantiationError: org.quartz.JobDetail makes tomcat9 start failed in linux but fine in windows
我有一个 restful api 应用程序在 spring 4 和 运行s 在 tomcat 7 上开发(使用 jdk8)
现在我尝试将它部署到 tomcat 9(build&运行 with jdk8),构建的 war 文件没有任何问题。但是linux中的tomcat9启动失败,错误是:
17:44:02:821 WARN [XmlWebApplicationContext] - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ediFeedTask' defined in class path resource [spring-scheduler.xml]: Invocation of init method failed; nested exception is java.lang.InstantiationError: org.quartz.JobDetail
17:44:02:839 ERROR [ContextLoader] - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ediFeedTask' defined in class path resource [spring-scheduler.xml]: Invocation of init method failed; nested exception is java.lang.InstantiationError: org.quartz.JobDetail
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583) ~[spring-beans-4.2.9.RELEASE.jar:4.2.9.RELEASE]
基本上它无法实例化在spring quartz xml 中定义的bean。因为如果我注释掉 spring-scheduler.xml 中的所有 beans 定义,应用程序将成功启动。这些 bean 都是预定的作业。
但我不明白为什么 tomcat9 为 quartz 调度程序实例化 bean 时出现问题。它在其他 xml 中很好地实例化 bean,例如 api-config.xml 或 spring-controller.xml。
最奇怪的是,同样的war文件在windows tomcat 9部署并启动成功,只是在tomcat 8和9在linux (ubuntu, deepin),请问有人知道吗?
下面是我的spring-scheduler.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="ediFeedJob" class="com.ai.api.job.EDIFeedJob" />
<bean id="ediFeedTask"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="concurrent" value="false" />
<property name="targetObject" ref="ediFeedJob" />
<property name="targetMethod" value="execute" />
</bean>
<bean id="ediFeedCronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="ediFeedTask" />
<property name="cronExpression" value="0 2 * * * ?"/>
</bean>
<bean id="startQuartz" lazy-init="false"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="ediFeedCronTrigger" />
</list>
</property>
</bean>
</beans>
实际上这是一个 maven 依赖问题。它不像我们通常看到的 "XXX class not found" 那样明显,但在这种情况下它抱怨 "InstantiationError: org.quartz.JobDetail" —— 所以我们可以假设 spring 本身有问题。
检查maven 依赖冲突后,我可以看到spring-beans 2.0.3 被引用,而通常它应该至少比4.0 更新。所以排除它
<dependency>
<groupId>org.springmodules</groupId>
<artifactId>spring-modules-jakarta-commons</artifactId>
<version>${spring.modules.jakarta.commons.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-support</artifactId>
</exclusion>
</exclusions>
然后问题解决了。
我有一个 restful api 应用程序在 spring 4 和 运行s 在 tomcat 7 上开发(使用 jdk8) 现在我尝试将它部署到 tomcat 9(build&运行 with jdk8),构建的 war 文件没有任何问题。但是linux中的tomcat9启动失败,错误是:
17:44:02:821 WARN [XmlWebApplicationContext] - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ediFeedTask' defined in class path resource [spring-scheduler.xml]: Invocation of init method failed; nested exception is java.lang.InstantiationError: org.quartz.JobDetail 17:44:02:839 ERROR [ContextLoader] - Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ediFeedTask' defined in class path resource [spring-scheduler.xml]: Invocation of init method failed; nested exception is java.lang.InstantiationError: org.quartz.JobDetail at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583) ~[spring-beans-4.2.9.RELEASE.jar:4.2.9.RELEASE]
基本上它无法实例化在spring quartz xml 中定义的bean。因为如果我注释掉 spring-scheduler.xml 中的所有 beans 定义,应用程序将成功启动。这些 bean 都是预定的作业。
但我不明白为什么 tomcat9 为 quartz 调度程序实例化 bean 时出现问题。它在其他 xml 中很好地实例化 bean,例如 api-config.xml 或 spring-controller.xml。
最奇怪的是,同样的war文件在windows tomcat 9部署并启动成功,只是在tomcat 8和9在linux (ubuntu, deepin),请问有人知道吗?
下面是我的spring-scheduler.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="ediFeedJob" class="com.ai.api.job.EDIFeedJob" />
<bean id="ediFeedTask"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="concurrent" value="false" />
<property name="targetObject" ref="ediFeedJob" />
<property name="targetMethod" value="execute" />
</bean>
<bean id="ediFeedCronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="ediFeedTask" />
<property name="cronExpression" value="0 2 * * * ?"/>
</bean>
<bean id="startQuartz" lazy-init="false"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="ediFeedCronTrigger" />
</list>
</property>
</bean>
</beans>
实际上这是一个 maven 依赖问题。它不像我们通常看到的 "XXX class not found" 那样明显,但在这种情况下它抱怨 "InstantiationError: org.quartz.JobDetail" —— 所以我们可以假设 spring 本身有问题。
检查maven 依赖冲突后,我可以看到spring-beans 2.0.3 被引用,而通常它应该至少比4.0 更新。所以排除它
<dependency>
<groupId>org.springmodules</groupId>
<artifactId>spring-modules-jakarta-commons</artifactId>
<version>${spring.modules.jakarta.commons.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-support</artifactId>
</exclusion>
</exclusions>
然后问题解决了。