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>

然后问题解决了。