使用easyexcel时遇到Could not initialize class net.sf.cglib.beans.BeanMap$Generator
可以访问 这里 查看更多关于大数据平台建设的原创文章。
上一篇文章 Maven项目为什么会产生NoClassDefFoundError的jar包冲突 结合了大量的图解,详细介绍了Maven项目产生jar包冲突的原因,以及为什么在编译的时候不报错,在运行的时候会报错的场景分析;
本篇记录一下在项目开发中使用Alibaba的开源组件easyexcel做excel文件上传和下载功能时,遇到的一个jar包冲突问题的排查思路和解决办法。
一. 问题现象
在使用alibaba的easyexcel工具开发excel的上传和下载功能时,本机环境测试没有问题,部署到测试环境时,却发现下载excel文件的功能一直异常,查看后台服务报错日志如下:
nested exception is com.alibaba.excel.exception.ExcelGenerateException: java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.beans.BeanMap$Generator] with root cause]
java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.beans.BeanMap$Generator
上一篇 Maven项目为什么会产生NoClassDefFoundError的jar包冲突 时 已经介绍过,看到 NoClassDefFoundError类似的异常时,大多数都是因为jar包冲突引起的。
二. 问题排查流程
由于本地开发环境无法浮现,所以只能从测试环境着手排查。
1. 解压jar包
登录项目部署的docker容器,解压项目jar包,将解压后的文件放入 app 文件夹里:
2. 查找jar包里有没有cglib.beans.BeanMap类
进入解压后的 app 目录,查找 cglib 包:
发现,解压后的 jar包里是存在 cglib.beans.BeanMap$Generator 这个类。
3. 继续看其它错误日志
继续看错误日志,发现这段:
大概意思是:
ClassVisitor 定义的是一个 interface,但是现在却作为一个父类(super class)被其它类继承了。
这种情况表明,此时应该存在jar包冲突了:
ClassVisitor 在一个jar包中是一个 interface;
在另一个jar包中却是一个 class。
4. 从刚刚解压的项目jar包里查找asm包
由于这个报错信息里包含asm,所以尝试查找包含asm的jar包:

发现竟然有两个不同版本的jar包。。。
三. 问题原因
为什么一个项目打出的 jar包里会有两个 asm 包呢?
1.项目哪些jar包依赖了asm包
使用 Maven helper 搜索 asm:

easyexcel 2.1.6 依赖 cglib 3.1,cglib又依赖 asm 4.2;
项目的springboot版本是2.0.0.M6,底层会依赖 asm 3.1。
2. 为什么会有两个版本的asm包?
从Maven 官方网站里搜索 asm 包:

发现有两个 artifactId 都叫 asm(但groupId 不一样),点击第2个 asm,查看详情:

也就是说 gropuId 为 asm 的包,从3.3.1版本后不再维护了,后续版本迁移到 gropuId为 org.ow2.asm 的 asm 包。
看到这里,结论已经出来:
asm 包从3.3.1 往后,gropuId 发生了变更(由asm 变更 org.ow2.asm);
由于项目使用的springboot版本是2.0.0,需要依赖asm3.0,easyexcel 2.1.6 依赖的是asm 4.2;
导致 Maven 在打包的时候将这两个 asm包( artifactId 一样,但groupId 不一样)都打进去了。
四. 问题解决
1. 该使用哪个版本的asm包?
到现在为止,已经在排查过程中也得到了有用的报错信息:
翻译过来就是: ClassVisitor 定义的是一个 interface,但是现在却作为一个父类(super class)被其它类继承了
并且也理清了产生冲突的原因:项目jar包里包含两个asm包,现在要确定项目使用哪个版本的asm包。
于是,从本机的 Maven 仓库里 分别找到 asm3.1 和 asm4.2 的包,并在 Idea 里打开ClassVisitor.class:
asm3.1:

asm4.2:

可以看到:
asm3.1的
ClassVisitor.class是 interface,asm4.2的ClassVisitor.class是 class;再结合报错信息,确定项目应该使用 asm3.1 的包。
2. 怎么解决冲突
由于asm 4.2是由 easyexcel 2.1.6 的依赖 cglib 3.1 引入的,因此降级 cglib 的版本,直接在pom.xml里引入低版本的 cglib 即可:
更新依赖,再次使用Maven helper查看:

可以看到:asm 版本已经降级成功。
使用 Jenkins 编译、打包、部署至测试环境后,再次测试项目的 excel 下载功能已经可以正常使用,jar包冲突导致的问题已经解决。
关注微信公众号
欢迎大家关注我的微信公众号阅读更多原创文章:
使用easyexcel时遇到Could not initialize class net.sf.cglib.beans.BeanMap$Generator的更多相关文章
- 异常-----java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.core.KeyFactory
SSH 类库问题 java.lang.NoClassDefFoundError: Could not initialize class net.sf.cglib.proxy.Enhancer2009- ...
- java.lang.NoClassDefFoundError: Could not initialize class net.sf.json.util.JSONUtils
页面报错: root: java.lang.NoClassDefFoundError: Could not initialize class net.sf.json.util.JSONUtils 出错 ...
- 异常:Caused by: java.lang.NoClassDefFoundError: Could not initialize class net.sf.log4jdbc.Properties
参考文章: 使用Log4jdbc-log4j2监听MyBatis中运行的SQL和Connection 使用 log4jdbc格式化输出SQL,maven配置如下: <dependency> ...
- 【EasyExcel】使用easyExcel过程中,项目报错的解决集合
报错:Can not close IO [ERROR] 2019-11-02 13:51:21.210 [ProExportSkuDataJob-1455-TaskThread-1] [com.dma ...
- 就因为加了Lombok的@Accessors(chain = true),bean拷贝工具类不干活了
前言 这次新建了一个工程,因为 Lombok 用得很习惯,但以前的话,一般只用了@Data,@AllArgsConstructor,@EqualsAndHashCode等常规注解:那这个Accesso ...
- 动态代理(二)—— CGLIB代理原理
前篇文章动态代理(一)--JDK中的动态代理中详细介绍了JDK动态代理的Demo实现,api介绍,原理详解.这篇文章继续讨论Java中的动态代理,并提及了Java中动态代理的几种实现方式.这里继续介绍 ...
- JAVA中JavaBean对象之间属性拷贝的方法
JAVA中JavaBean对象之间的拷贝通常是用get/set方法,但如果你有两个属性相同的JavaBean或有大部分属性相同的JavaBean,对于这种情况,可以采用以下几个简便方法处理. 下面对这 ...
- Java动态代理全面分析
代理模式 解说:给某一个对象提供一个代理,并由代理对象控制对原对象的引用: 代理模式需要以下几个角色: 1 主题:规定代理类和真实对象共同对外暴露的接口: 2 代理类:专门代理真实对象的类: 3 ...
- Java动态代理与Cglib库
JDK动态代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在 ...
随机推荐
- 基于 JavaEmail 简单的发送邮件点到点,一对多(图片和附件)之多收件人,多少送人
if(!StringUtil.isEmpty(message_type_to)){ if (message_type_to.contains(",")) { String[] sp ...
- Paper English
论文中的英语 单词 a arange 整理 ambiguity 含糊的 aggregate 总量 auxiliary 辅助的 alleviate 缓解 aberrant 异常的 akin 类似的 Ac ...
- PyTorch上路
PyTorch torch.autograd模块 深度学习的算法本质上是通过反向传播求导数, PyTorch的autograd模块实现了此功能, 在Tensor上的所有操作, autograd都会为它 ...
- Java高级篇反射和注解
反射是什么? 反射的作用?能带来什么好处? 反射的使用? 注解的使用? 注解和反射配合实战...
- C#LeetCode刷题之#83-删除排序链表中的重复元素(Remove Duplicates from Sorted List)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3820 访问. 给定一个排序链表,删除所有重复的元素,使得每个元素 ...
- DRF内置认证组件之自定义认证系统
自定义token认证 我们知道,在django项目中不管路由以及对应的视图类是如何写的,都会走到 dispatch 方法,进行路由分发, 在阅读 APIView类中的dispatch 方法的源码中,有 ...
- JavaScript基础-01
1. Javascript是一门动态的.弱类型的.解释型的脚本语言 动态:数据类型在运行时决定 弱类型:变量数据的类型不是确定的,可以随意的进行改变: 解释型:相对编译型来说,编译型计算机在执行之前需 ...
- dota2输入法无候选框?
win10自带的微软拼音在dota2中不会显示候选框,或者说是选词框. 这种情况下只能选择其他输入法. 我选择的是搜狗输入法(此随笔添加时的最新版),在dota2中有选词框. 网上有些人说要改兼容性, ...
- Mybatis-08-动态SQL
动态SQL 什么是动态SQL? 根据不同的条件生成不同的SQL语句. if choose(where,otherwise) trim(where,set) foreach 搭建环境 create ta ...
- troubleshoot之:使用JFR分析性能问题
目录 简介 GC性能事件 同步性能 IO性能 代码执行的性能 其他有用的event 简介 java程序的性能问题分析是一个很困难的问题.尤其是对于一个非常复杂的程序来说,分析起来更是头疼. 还好JVM ...