写在前面 其实写代码,很多时候。有些人真的习惯不好,遇到一个需求,什么依赖。一梭子直接往上堆,就导致后面莫名其妙遇到一些问题。让人摸不着头脑。
学东西也是一样,要知道它为什么要这样弄,并且需要去理解它的内在,而不是耍表面功夫。
这个BUG让人难受了一下午,我特意记录一下。
需求依赖 很多数据型的系统,都有导出Excel的功能,我们当前的系统亦是如此。
https://github.com/alibaba/easyexcel
引入了一个Alibaba的官方Excel工具,用来导出Excel. 依赖信息如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <dependency > <groupId > com.alibaba</groupId > <artifactId > easyexcel</artifactId > <version > 3.1.1</version > </dependency > <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi</artifactId > <version > 4.1.0</version > </dependency > <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi-ooxml</artifactId > <version > 4.1.0</version > </dependency >
异常信息 1 2 3 4 5 6 Caused by: java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.Cell.setCellValue(Ljava/time/LocalDateTime;)V at com.alibaba.excel.write.executor.AbstractExcelWriteExecutor.converterAndSet(AbstractExcelWriteExecutor.java:95 ) at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.addJavaObjectToExcel(ExcelWriteAddExecutor.java:174 ) at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.addOneRowOfDataToExcel(ExcelWriteAddExecutor.java:82 ) at com.alibaba.excel.write.executor.ExcelWriteAddExecutor.add(ExcelWriteAddExecutor.java:58 ) at com.alibaba.excel.write.ExcelBuilderImpl.addContent(ExcelBuilderImpl.java:59 )
丛上面的异常信息中,可以得出:没有指定的方法,大致意思是,要执行的方法没找到。有的时候在多态调用的时候,就会发生这样的问题。
NoSuchMethodError (Java Platform SE 8 )
排查过程 通过堆栈信息查找问题的时候,需要进行下载源码查看,不然你报错的位置可能和你打开所看到的位置不一样。你很容易摸不着头脑。
1 2 case DATE: cell.setCellValue(cellData.getDateValue());
发现cellData.getDataValue()
这个方法返回的是一个LocalDateTime
类型
1 private LocalDateTime dateValue;
但是在Cell
这个接口中,有如下定义:
1 2 3 4 5 6 7 8 9 void setCellValue (double var1) ;void setCellValue (Date var1) ;void setCellValue (Calendar var1) ;void setCellValue (RichTextString var1) ;void setCellValue (String var1) ;
有Date类型的参数,就是没有LocalDateTime
类型的参数,就很离谱,所以没有找到对应的方法,也就说得通了。
为啥没有类型为LocalDateTime
的这个参数呢?
从 Cell
这个对象着手,发现它来自这个包,而这个包所属于如下的依赖;非常纳闷
1 package org.apache.poi.ss.usermodel
1 2 3 4 5 <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi</artifactId > <version > 4.1.0</version > </dependency >
打开Maven工具分析依赖
注意红色的位置:
项目一共引用了三个依赖:
easyexcel
poi
poi-ooxml
而easyexcel里面又有 core
与 slf4j-api
.core包又依赖了poi
包和poi-ooxml
包
打开 easyexcel-core
的包发现:引用了如下4.1.2版本
1 2 3 4 5 6 7 8 9 10 11 12 <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi</artifactId > <version > 4.1.2</version > <scope > compile</scope > </dependency > <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi-ooxml</artifactId > <version > 4.1.2</version > <scope > compile</scope > </dependency >
但是我在我项目的目录下引用了:4.1.0版本
1 2 3 4 5 6 7 8 9 10 <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi</artifactId > <version > 4.1.0</version > </dependency > <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi-ooxml</artifactId > <version > 4.1.0</version > </dependency >
于是乎:就发生了版本的覆盖问题。即上层的版本(4.1.0)虽然版本号比较低,但是优先级较高,与同样在较低层级的(4.1.2)虽然版本较高,但还是被覆盖了
最终使用我的项目使用了4.1.0的版本
最后官方的文档也证明:在4.1.2版本修正了这个BUG
https://bz.apache.org/bugzilla/show_bug.cgi?id=64044
1 Fix issue with setCellValue (LocalDate) not supporting nulls properly
所以,你就知道该怎么操作了
我学到了什么 参考链接 https://github.com/alibaba/easyexcel
NoSuchMethodError (Java Platform SE 8 )
https://poi.apache.org/changes.html