可以访问 这里 查看更多关于大数据平台建设的原创文章。

  1. 上一篇文章 Maven项目为什么会产生NoClassDefFoundError的jar包冲突 结合了大量的图解,详细介绍了Maven项目产生jar包冲突的原因,以及为什么在编译的时候不报错,在运行的时候会报错的场景分析;

  2. 本篇记录一下在项目开发中使用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 文件夹里:

[root@08e08117bd99 /]# cd /data/application/java
[root@08e08117bd99 /data/application/java]# unzip app.jar -d app/

2. 查找jar包里有没有cglib.beans.BeanMap类

进入解压后的 app 目录,查找 cglib 包:

[root@08e08117bd99 /data/application/java]# cd /app/BOOT-INF/lib
$ ls -l | grep cglib
-rw-r--r-- 1 root root 283080 Dec 7 2013 cglib-3.1.jar
# 继续解压cglib包
[root@08e08117bd99 /data/application/java/app/BOOT-INF/lib]# unzip -l cglib-3.1.jar | grep BeanMap
336 12-07-2013 11:28 net/sf/cglib/beans/BeanMap$Generator$BeanMapKey.class
3219 12-07-2013 11:28 net/sf/cglib/beans/BeanMap$Generator.class
5008 12-07-2013 11:28 net/sf/cglib/beans/BeanMap.class
1825 12-07-2013 11:28 net/sf/cglib/beans/BeanMapEmitter$1.class
2090 12-07-2013 11:28 net/sf/cglib/beans/BeanMapEmitter$2.class
1546 12-07-2013 11:28 net/sf/cglib/beans/BeanMapEmitter$3.class
6339 12-07-2013 11:28 net/sf/cglib/beans/BeanMapEmitter.class

发现,解压后的 jar包里是存在 cglib.beans.BeanMap$Generator 这个类。

3. 继续看其它错误日志

继续看错误日志,发现这段:

class net.sf.cglib.core.DebuggingClassWriter has interface org.objectweb.asm.ClassVisitor as super class

大概意思是:

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包?

到现在为止,已经在排查过程中也得到了有用的报错信息

class net.sf.cglib.core.DebuggingClassWriter has interface org.objectweb.asm.ClassVisitor as super class

翻译过来就是: 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 即可:

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>

更新依赖,再次使用Maven helper查看:

​可以看到:asm 版本已经降级成功。

​使用 Jenkins 编译、打包、部署至测试环境后,再次测试项目的 excel 下载功能已经可以正常使用,jar包冲突导致的问题已经解决。

关注微信公众号

欢迎大家关注我的微信公众号阅读更多原创文章:

使用easyexcel时遇到Could not initialize class net.sf.cglib.beans.BeanMap$Generator的更多相关文章

  1. 异常-----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- ...

  2. 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 出错 ...

  3. 异常:Caused by: java.lang.NoClassDefFoundError: Could not initialize class net.sf.log4jdbc.Properties

    参考文章: 使用Log4jdbc-log4j2监听MyBatis中运行的SQL和Connection 使用 log4jdbc格式化输出SQL,maven配置如下: <dependency> ...

  4. 【EasyExcel】使用easyExcel过程中,项目报错的解决集合

    报错:Can not close IO [ERROR] 2019-11-02 13:51:21.210 [ProExportSkuDataJob-1455-TaskThread-1] [com.dma ...

  5. 就因为加了Lombok的@Accessors(chain = true),bean拷贝工具类不干活了

    前言 这次新建了一个工程,因为 Lombok 用得很习惯,但以前的话,一般只用了@Data,@AllArgsConstructor,@EqualsAndHashCode等常规注解:那这个Accesso ...

  6. 动态代理(二)—— CGLIB代理原理

    前篇文章动态代理(一)--JDK中的动态代理中详细介绍了JDK动态代理的Demo实现,api介绍,原理详解.这篇文章继续讨论Java中的动态代理,并提及了Java中动态代理的几种实现方式.这里继续介绍 ...

  7. JAVA中JavaBean对象之间属性拷贝的方法

    JAVA中JavaBean对象之间的拷贝通常是用get/set方法,但如果你有两个属性相同的JavaBean或有大部分属性相同的JavaBean,对于这种情况,可以采用以下几个简便方法处理. 下面对这 ...

  8. Java动态代理全面分析

    代理模式 解说:给某一个对象提供一个代理,并由代理对象控制对原对象的引用: 代理模式需要以下几个角色: 1  主题:规定代理类和真实对象共同对外暴露的接口: 2  代理类:专门代理真实对象的类: 3 ...

  9. Java动态代理与Cglib库

    JDK动态代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在 ...

随机推荐

  1. Java助教工作总结

    很荣幸在步入在研究生之际,有机会能协助代老师完成面向对象程序设计(java)课程的教学工作.这也是我人生中第一次接触助教工作,好多东西不太清楚,也没经验,有什么做的不好的,还望老师同学及时指出. 上周 ...

  2. 老板让我从上千个Excel中筛选数据,利用Python分分钟解决!

    大家好,又到了Python办公自动化系列. 今天分享一个真实的办公自动化需求,大家一定要仔细阅读需求说明,在理解需求之后即可体会Python的强大! 很多人学习python,不知道从何学起.很多人学习 ...

  3. Python初学者的自我修养,找到自己的方向

    今天是 Python专题 的第22篇文章,原本今天是准备和大家继续Python当中多线程的使用的相关内容.然而前两天有一个读者在后台问我,学习Python有哪些适合新手入门的小项目推荐,所以今天这篇临 ...

  4. PHP入门之数组

    前言 之前几篇文章分别介绍了PHP的运算符,流程控制,函数.有兴趣的可以去看看. PHP入门之类型与运算符 PHP入门之流程控制 PHP入门之函数 接下来简单介绍一下数组. 数组初探 为什么要引进数组 ...

  5. 尝试Access数据库注入实验

    靶场环境:https://www.mozhe.cn/bug/detail/82 首先http://219.153.49.228:49543/new_list.asp?id=1 order by 4 到 ...

  6. 在Springboot中写使用jsp

    jsp其实可以看成一种模板语言,在Springboot中我们同样可以使用jsp.我们可以把引入jsp的过程分为三步: 第一步:POM文件加依赖: <!--引入springboot内嵌的tomca ...

  7. 关于setTimeout的用法注意事项

    setTimeout setTimeout的定义:setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. setTimeout的用法:setTimeout(代码片段,执行代码等待的毫 ...

  8. C#LeetCode刷题之#530-二叉搜索树的最小绝对差(Minimum Absolute Difference in BST)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4123 访问. 给定一个所有节点为非负值的二叉搜索树,求树中任意两 ...

  9. Kinect+unity 实现体感格斗闯关小游戏

    文章目录 项目地址 1 项目概况 1.1 项目简介 1.2 项目目的 1.3 主要技术 2 设计 2.1 基本概念 2.2 框架 2.3 算法 2.4 模型 2.5 调查问卷 3 实现 3.1 技术难 ...

  10. 【NOIP必备攻略】 基本noilinux使用方法

    现在linux系统已经成为了NOIP竞赛的一大操作系统,如果连最基础的操作都不会,那就更别提怎么得分了,万一操作失误,可就爆零了.所以小编特意发这样一篇博客,教你快速上手noilinux! ▎ 常用操 ...