You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.4.1升级启动失败:Order注解类型转换异常排查

Java 17 + Spring Boot 3.4.1 升级后SFTP项目启动失败问题排查与解决

问题场景

将项目从Java 1.8升级到Java 17、Spring Boot 2.x升级到3.4.1后,多数项目迁移成功,但一个使用SFTP的项目无法启动。调试发现异常抛出点在org.springframework.integration.config.AbstractMethodAnnotationPostProcessor.processBeanDefinition方法第205行,代码尝试将@Order注解的Integer值转换为String类型时,触发java.lang.IllegalArgumentException(无法将Integer适配为String)。

项目配置

  • Java版本:17
  • spring-boot-starter-parent版本:3.4.1
  • tomcat.embed.core.version:10.1.35
  • spring-integration-core、spring-integration-file等集成组件使用spring-boot-starter-parent默认版本

异常触发代码片段

if (isClassIn(handlerBeanClass, Orderable.class, AbstractSimpleMessageHandlerFactoryBean.class)) {
    mergedAnnotations.get(Order.class)
            .getValue(AnnotationUtils.VALUE, String.class).
            ifPresent((order) -> handlerBeanDefinition.getPropertyValues().add("order", order));
}

异常栈信息

java.lang.IllegalArgumentException: Unable to adapt value of type java.lang.Integer to java.lang.String
    at org.springframework.core.annotation.TypeMappedAnnotation.adapt(TypeMappedAnnotation.java:483)
    at org.springframework.core.annotation.TypeMappedAnnotation.getValue(TypeMappedAnnotation.java:391)
    at org.springframework.core.annotation.TypeMappedAnnotation.getAttributeValue(TypeMappedAnnotation.java:372)
    at org.springframework.core.annotation.AbstractMergedAnnotation.getValue(AbstractMergedAnnotation.java:176)
    at org.springframework.integration.config.AbstractMethodAnnotationPostProcessor.processBeanDefinition(AbstractMethodAnnotationPostProcessor.java:205)
    at org.springframework.integration.config.MessagingAnnotationPostProcessor.processMessagingAnnotationOnBean(MessagingAnnotationPostProcessor.java:143)
    at org.springframework.integration.config.MessagingAnnotationPostProcessor.processCandidate(MessagingAnnotationPostProcessor.java:130)
    at org.springframework.integration.config.MessagingAnnotationPostProcessor.postProcessBeanDefinitionRegistry(MessagingAnnotationPostProcessor.java:99)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:148)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:791)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:609)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
    at com.msts.Application.main(Application.java:39)

项目pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.msts</groupId>
    <artifactId>transmit-file-command</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>transmit-file-command</name>
    <description>Transmit File</description>


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.1</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>17</java.version>
        <junit-jupiter.version>5.3.2</junit-jupiter.version>
        <axon.version>4.10.3</axon.version>
        <tomcat.embed.core.version>10.1.35</tomcat.embed.core.version>
    </properties>


    <dependencies>

        <!-- Spring Boot 2 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.tomcat.embed</groupId>
                    <artifactId>tomcat-embed-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>${tomcat.embed.core.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <!-- Flyway -->
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
            <version>9.22.3</version>
        </dependency>

        <!-- Spring Boot with data -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- Axon with Spring Boot -->
        <dependency>
            <groupId>org.axonframework</groupId>
            <artifactId>axon-spring-boot-starter</artifactId>
            <version>${axon.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.mwiede</groupId>
            <artifactId>jsch</artifactId>
            <version>0.2.16</version>
        </dependency>

        <!-- Postgresql DB -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.7.2</version>
        </dependency>

        <!-- AMZON SQS -->
        <!-- https://mvnrepository.com/artifact/software.amazon.awssdk/sqs -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-sqs</artifactId>
            <version>1.11.551</version>
        </dependency>

        <!-- Amazon SNS -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-sns</artifactId>
            <version>1.11.551</version>
        </dependency>

        <!-- GSON -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>

        <!-- Json Convert -->
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>[20241224,)</version>
        </dependency>

        <!-- Log back -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>

        <!-- Convert DTO to entity or viceversa -->
        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>2.3.2</version>
        </dependency>

        <!-- Common utils -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!-- Validations utils -->
        <dependency>
            <groupId>commons-validator</groupId>
            <artifactId>commons-validator</artifactId>
            <version>1.5.0</version>
        </dependency>

        <!-- Swagger API -->
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <version>2.7.0</version>
        </dependency>

        <!-- Spring Boot Test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- junit 5 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Allow conditional logic in XML file -->
        <dependency>
            <groupId>org.codehaus.janino</groupId>
            <artifactId>janino</artifactId>
        </dependency>

        <!-- aws dynamodb -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-dynamodb</artifactId>
            <version>1.11.661</version>
        </dependency>

        <!-- APACHE Http Client -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.14</version>
        </dependency>

        <dependency>
            <groupId>com.github.derjust</groupId>
            <artifactId>spring-data-dynamodb</artifactId>
            <version>5.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-file</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
        </dependency>

        <!-- Spring FTP -->
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-ftp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-sftp</artifactId>
        </dependency>

        <!-- Spring SFTP -->

        <!-- <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-sftp</artifactId> 
        </dependency> -->

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
        </dependency>

        <!-- Flatfile parser -->
        <dependency>
            <groupId>com.github.ffpojo</groupId>
            <artifactId>ffpojo</artifactId>
            <version>1.0</version>
        </dependency>

        <!--login check -->
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.1</version> <!-- Use the latest version available -->
        </dependency>

        <dependency>
            <groupId>com.opencsv</groupId>
            <artifactId>opencsv</artifactId>
            <version>4.1</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-csv</artifactId>
            <version>2.11.1</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.11.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.13.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/software.amazon.awssdk/secretsmanager -->
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-secretsmanager</artifactId>
            <version>1.11.339</version>
        </dependency>

        <!-- Maven example -->
        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
            <version>4.25.1</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>transmit-file-command</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <addResources>true</addResources>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-maven-plugin</artifactId>
                <version>9.22.3</version>
            </plugin>
        </plugins>
    </build>
</project>

问题原因分析

  1. Spring Integration核心bug:Spring Boot 3.4.1集成的Spring Integration版本中,AbstractMethodAnnotationPostProcessor的代码逻辑错误——@Order注解的value属性本身是int类型,但代码强行指定String.class作为目标类型去获取值,而Spring的注解值适配机制不支持Integer到String的直接转换,导致抛出类型转换异常。
  2. 依赖版本冲突隐患:pom.xml中存在多处依赖版本不一致问题(如Jackson的2.11.1和2.13.2版本共存),以及使用了javax.的JAXB旧依赖(Spring Boot 3.x已迁移到Jakarta EE规范,对应依赖应为jakarta.),这些虽然不是直接触发启动失败的原因,但会引发其他潜在问题。

解决方案

1. 修复Spring Integration核心bug

Spring Integration 6.2.5及以上版本已修复该类型转换问题,可通过两种方式升级:

  • 方式一:升级Spring Boot版本:将spring-boot-starter-parent版本升级到3.4.2及以上,新版本会自动集成修复后的Spring Integration版本。
  • 方式二:显式指定Spring Integration版本:在pom.xml的properties中添加版本配置:
    <properties>
        <spring-integration.version>6.2.5</spring-integration.version>
    </properties>
    

2. 清理依赖冲突与适配Jakarta规范

  • 替换JAXB依赖:移除javax.xml.bind、javax.activation等旧依赖,替换为Jakarta EE对应的依赖:
    <dependency>
        <groupId>jakarta.xml.bind</groupId>
        <artifactId>jakarta.xml.bind-api</artifactId>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <scope>runtime</scope>
    </dependency>
    
  • 统一Jackson版本:移除所有Jackson依赖的显式version标签,让Spring Boot parent统一管理版本,避免版本不一致:
    <dependency>
        <groupId>
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 05:14:58