当前位置: 首页 > news >正文

Java 17 环境下 EasyPoi 反射访问异常分析与解决方案(ExcelImportUtil.importExcelMore)

问题描述

在 Java 17 环境中使用 EasyPoi 进行 Excel 导入操作时(ExcelImportUtil.importExcelMore),出现以下反射访问异常:

java.lang.reflect.InaccessibleObjectException: Unable to make field final boolean java.util.LinkedHashMap.accessOrder accessible: module java.base does not "opens java.util" to unnamed module @6da21078at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)at java.base/java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:130)at org.apache.commons.lang3.builder.ReflectionToStringBuilder.appendFieldsIn(ReflectionToStringBuilder.java:649)at org.apache.commons.lang3.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:853)at org.apache.commons.lang3.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:387)at org.apache.commons.lang3.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:156)at cn.afterturn.easypoi.excel.imports.ExcelImportService.importExcel(ExcelImportService.java:270)at cn.afterturn.easypoi.excel.imports.ExcelImportService.importExcelByIs(ExcelImportService.java:482)at cn.afterturn.easypoi.excel.ExcelImportUtil.importExcelMore(ExcelImportUtil.java:99)

原因分析:

  1. Java 模块系统限制
    Java 9 引入了模块系统(JPMS),在 Java 17 中进一步加强了封装性。java.base 模块中的 java.util 包默认不对未命名模块开放反射访问权限。

  2. EasyPoi 内部实现
    EasyPoi 在处理 Excel 导入时,内部使用了 Apache Commons Lang 的 ReflectionToStringBuilder 进行反射操作,试图访问 LinkedHashMap.accessOrder 字段。

  3. 依赖版本兼容性
    我这边使用的是新版本的 EasyPoi (4.5.0) 和 Commons Lang3 (3.17.0),在某些 Java 17+ 环境中仍然会遇到此问题。


解决方案:

方案一:添加 JVM 参数

在启动命令中添加,详细可看官网对此描述官网

java --add-opens java.management/sun.management=ALL-UNNAMED

方案二:使用其他方式实现,例如Apache POI、Easyexcel等

public void import(MultipartFile vettingFile) {// 创建 DataFormatter 用于格式化单元格值DataFormatter dataFormatter = new DataFormatter();InputStream inputStream = null;Workbook workbook = null;List<Map<String, Object>> resultList = new ArrayList<>();try (InputStream inputStream= vettingFile.getInputStream()) {workbook = new XSSFWorkbook(inputStream);// 解析 Excel 文件Sheet sheet = workbook.getSheetAt(0);// 读取标题行(第5行,索引4)Row headerRow = sheet.getRow(4);if (headerRow == null) {return Result.succeed("analyzing-import-file-failed");}// 构建列映射Map<Integer, String> columnMapping = new HashMap<>();for (int i = 0; i < headerRow.getLastCellNum(); i++) {Cell cell = headerRow.getCell(i);if (cell != null) {// 清理列名:去除换行符和前后空格String columnName = dataFormatter.formatCellValue(cell).replace("\n", " ").replace("\r", "").trim();if (!columnName.isEmpty()) {columnMapping.put(i, columnName);}}}// 读取数据行(从第6行开始,索引5)for (int i = 5; i <= sheet.getLastRowNum(); i++) {Row row = sheet.getRow(i);if (row == null) continue;Map<String, Object> rowData = new HashMap<>();boolean hasData = false;for (Map.Entry<Integer, String> entry : columnMapping.entrySet()) {int colIndex = entry.getKey();String columnName = entry.getValue();Cell cell = row.getCell(colIndex);// 清理单元格值String cellValue = dataFormatter.formatCellValue(cell).replace("\n", " ").replace("\r", "").trim();if (!cellValue.isEmpty()) {hasData = true;}rowData.put(columnName, cellValue);}if (hasData) {resultList.add(rowData);}}} catch (Exception ex) {log.error("Analyze import file exception: ", ex);} finally {// 关闭资源closeResources(workbook, inputStream, poifs);}
}// 资源关闭辅助方法
private void closeResources(Workbook workbook, InputStream inputStream) {try {if (workbook != null) {workbook.close();}if (inputStream != null) {inputStream.close();}} catch (Exception ex) {log.error("Close resources exception: ", ex);}

}

http://www.dtcms.com/a/519423.html

相关文章:

  • SpringBoot+alibaba的easyexcel实现前端使用excel表格批量插入
  • 重大更新,LVGL有UI编辑器用了
  • 多场景 VR 教学编辑器:重构教学流程的场景化实践
  • 公司做网站让我们销售单页面网站模板怎么做
  • 广州微网站建设价位广东网站建设公司
  • 基于 Spring AI Alibaba + Nacos 的分布式 Multi-Agent 构建指南
  • 《与幽灵作战:Python 棘手 Bug 的调试策略与实战技巧》
  • 使用Requests和lxml实现飞卢小说网小说爬取
  • bug 记录 - 路由守卫 beforeRouteLeave 与 confirm 结合,不生效问题
  • 数据库字段类型bit容易被忽视的bug
  • centos 配置网络
  • [人工智能-大模型-55]:模型层技术 - AI的算法、数据结构中算法、逻辑处理的算法异同
  • LeetCode 3461.判断操作后字符串中的数字是否相等 I:简单题简单做的时候到了
  • IPhone 17 Pro Max拍摄专业画质视频教程
  • MoE大模型分布式训练:Switch Transformer与专家并行策略
  • 网站设置评价青岛企业网站建设优化
  • MySQL 增删改查操作与 SQL 执行顺序
  • 静态Web应用与JavaScript:现代前端开发的新范式
  • 按键精灵安卓/iOS脚本辅助,OpenCV实现自动化高效率工具
  • 2510rs,rust,1.90
  • 厦门小微企业网站建设补贴wordpress 评论弹幕
  • Prometheus(二)—— 在K8s集群中部署Prometheus+Grafana+AlertManager实现全方位监控
  • 论文学习_One Bug, Hundreds Behind: LLMs for Large-Scale Bug Discovery
  • 18.InnoDB 存储引擎(存储结构)
  • ⸢ 玖 ⸥⤳ 威胁感知与响应体系概念及建设思路
  • 芯谷科技--高性能直流有刷电机调速电路GS016
  • Shell脚本切换家庭和随身wifi网络配置
  • 化妆品网站建设方案项目书有区域名和主机怎么做网站
  • String[ ] 和 List<String> 的区别
  • el-table默认排序设置