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

Spring Boot加载FatJar插件时IOUtils.byteArray方法找不到问题求助

问题分析与解决方案

核心原因

这个错误的本质是类加载器双亲委派机制导致的版本冲突:

  • 应用的类加载器(Spring Boot的类加载器)作为UrlClassLoader的父加载器,会优先加载org.apache.commons.io.IOUtils类。如果应用中存在低版本的commons-io(没有byteArray(int)方法),即使插件FatJar里包含高版本的类,也会被父加载器的旧版本覆盖,从而抛出NoSuchMethodError。

解决方案

方案1:自定义类加载器,优先加载插件内部依赖

实现一个自定义ClassLoader,重写loadClass方法,指定插件内部的特定包(比如org.apache.commons.io)优先从插件Jar中加载,其他类遵循双亲委派规则。

示例代码:

public class PluginClassLoader extends URLClassLoader {
    private static final String PRIORITY_PACKAGE = "org.apache.commons.io.";

    public PluginClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
    }

    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        // 优先加载指定包下的类
        if (name.startsWith(PRIORITY_PACKAGE)) {
            synchronized (getClassLoadingLock(name)) {
                Class<?> c = findLoadedClass(name);
                if (c == null) {
                    c = findClass(name);
                }
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
        }
        // 其他类走双亲委派
        return super.loadClass(name, resolve);
    }
}

加载插件时使用这个自定义类加载器,替代默认的UrlClassLoader。

方案2:Gradle Shadow插件重定位依赖包

通过Gradle的Shadow插件,将插件中的commons-io依赖包重命名为插件专属的包路径,避免与应用中的依赖类名冲突。

在插件的build.gradle中配置:

plugins {
    id 'java'
    id 'com.github.johnrengelman.shadow' version '7.1.2'
}

shadowJar {
    // 将org.apache.commons.io重定位到插件专属包
    relocate 'org.apache.commons.io', 'com.your.plugin.commons.io'
}

构建后,插件FatJar中的commons-io类会被重命名,不会与应用中的类产生冲突,类加载器会正确加载插件内的版本。

方案3:排除应用对commons-io的依赖(谨慎使用)

如果应用本身并不依赖commons-io,可以在应用的Maven pom.xml中排除所有传递依赖中的commons-io:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>0.0.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

这种方式需要确保应用自身不会用到commons-io,否则会引发新的类找不到错误。

验证步骤

  • 构建插件后,解压FatJar确认:
    • 方案2下,是否存在重命名后的包路径(比如com/your/plugin/commons/io);
    • 方案1下,通过日志或调试确认插件的IOUtils类是由自定义类加载器加载的。

内容的提问来源于stack exchange,提问作者ivvasch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 15:07:05