【分享排雷经历】系统引入Apache-Tika产生的NoClassDefFoundError错误

简介: 为实现文件导入的安全控制,在系统中引入了基于`Apache Tika`的文件类型校验机制。但在运行时出现`NoClassDefFoundError`,提示缺少`commons-io`类。经排查发现,`monorepo`依赖的`commons-io`版本(2.6)低于Tika 2.9.1所需版本(2.16.1)。由于系统依赖统一管理,直接升级`commons-io`可能影响其他模块。最终解决方案为降级Tika版本至2.4.1,该版本兼容`commons-io:2.6`,问题得以解决且功能满足需求。

今天,我们的重点工作是对monorepo系统的文件导入做安全控制,主要是通过判断文件的扩展名和类型,来限定用户导入文件的合法性,防止非法文件进入系统造成风险。

我们借用了此前在另一个系统zfquan基于Apache Tika的解决方案。

不巧,在运行main程序时,出现了一个 NoClassDefFoundError 错误-未找到Apache Commons IO(commons-io)类库的一个class的定义

20:25:14.667 [main] DEBUG org.apache.tika.config.TikaConfig - loading tika config from defaults; no config file specified
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/io/input/UnsynchronizedByteArrayInputStream
    at org.apache.tika.config.TikaConfig.getDefaultMimeTypes(TikaConfig.java:317)
    at org.apache.tika.config.TikaConfig.<init>(TikaConfig.java:246)
    at org.apache.tika.config.TikaConfig.getDefaultConfig(TikaConfig.java:390)
    at org.apache.tika.Tika.<init>(Tika.java:119)
    at com.emax.zhenghe.common.util.TikaFileSecurityUtils.<init>(TikaFileSecurityUtils.java:20)
    at com.emaxcard.car.TestMain.main(TestMain.java:38)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.io.input.UnsynchronizedByteArrayInputStream
    at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
    ... 6 more

Process finished with exit code 1


NoClassDefFoundError(而不是 ClassNotFoundException) 表示编译时类存在,但运行时找不到。

常见原因:

  • 依赖未正确引入。

  • 依赖冲突导致类加载失败。

  • 打包时遗漏了 commons-io.jar(如 maven-shade-plugin 未正确包含依赖)。




同样的Tika,为什么搬到monorepo就不行了呢?

经查maven依赖,monorepo系统与zfquan系统所依赖的 commons-io 的版本不同,zfquan2.16.1monorepo2.6,这导致了问题的发生。


与单体结构的zfquan所不同的是,monorepo是一个庞大的同时拥有基础lib库和上层应用的工程。我们是在lib库的 sby-component-dfs 包 中添加的Tika依赖。


我尝试在其中一个应用层pom里显式添加 commons-io:2.16.1,是可以解决问题的。

但,monorepo有多达数十个应用,我显然不能在这么多应用层里显式添加 commons-io:2.16.1 依赖。而且,这不符合我们的系统开发规范————maven包依赖统一在顶层pom来管理。


那么,如何继续解决呢?

通过应用的maven依赖树(dependency:tree)得知,commons-io:commons-io:jar:2.6 是直接作为顶层依赖引入的(没有被其他库传递依赖)

然后我在IDE中全局查找 <artifactId>commons-io</artifactId>,发现在顶层maven依赖管理文件 spring-base.pom 中,的确显式定义了 commons-io 的版本号!

<properties>
    ...
    <commons.version>2.6</commons.version>
</properties>

<dependencyManagement>
    <dependencies>
        ...
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>${commons.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

如此,我把这个版本号变更为 2.16.1 ,也是可以解决问题的。

但,monorepo项目庞大,这样可能会拆东墙补西墙————可能影响其他用到commons-io的系统功能。


so,我们得针对 Tika 版本来做文章,找到适配 commons-io:2.6 的版本。

DeepSeek很快给出答案:Tika 2.4.1依赖commons-io:2.6。开发者将 Tika 版本从 2.9.1 降级到 2.4.1,不再出现NoClassDefFoundError错误,并且经测试,这个版本的Tika可以满足我们对系统文件导入的安全控制。

目录
相关文章
|
消息中间件 Java API
面试官:如何实现链式调用?
面试官:如何实现链式调用?
704 0
|
Java 数据库连接 mybatis
【Mybatis用法】Mybatis框架中一对一,一对多association和collection的使用举例方法
【Mybatis用法】Mybatis框架中一对一,一对多association和collection的使用举例方法
388 0
|
安全 搜索推荐 数据挖掘
文件解析的终极工具:Apache Tika
文件解析的终极工具:Apache Tika
2081 0
|
6月前
|
机器学习/深度学习 人工智能 负载均衡
Trae 04.22版本深度解析:Agent能力升级与MCP市场对复杂任务执行的革新
在当今快速发展的AI技术领域,Agent系统正成为自动化任务执行和智能交互的核心组件。Trae作为一款先进的AI协作平台,在04.22版本中带来了重大更新,特别是在Agent能力升级和MCP市场支持方面。本文将深入探讨这些更新如何重新定义复杂任务的执行方式,为开发者提供更强大的工具和更灵活的解决方案。
757 1
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
3494 2
|
iOS开发 MacOS Windows
electron-updater实现electron全量版本更新
electron-updater实现electron全量版本更新
2158 9
electron-updater实现electron全量版本更新
|
消息中间件 数据采集 中间件
RabbitMQ的使用—实战
RabbitMQ的使用—实战
413 1
|
网络协议 Java Maven
多模块项目使用ElasticSearch报错
多模块项目使用ElasticSearch报错
350 6
|
缓存 前端开发
后端MultipartFile接收文件转Base64
后端MultipartFile接收文件转Base64
195 0
Error creating bean with name 'eurekaAutoServiceRegistration': Singleton bean creation not allowed while singletons
Error creating bean with name 'eurekaAutoServiceRegistration': Singleton bean creation not allowed while singletons
404 3