Java模块访问JPEGMetadata触发IllegalAccessError的解决求助
解决JDK17模块化应用访问JPEGMetadata的IllegalAccessError问题
方法一:通过JVM参数临时导出内部包
com.sun.imageio.plugins.jpeg是Java的内部私有包,模块系统默认不会将其开放给自定义模块。你可以在启动应用时添加以下JVM参数,强制让java.desktop模块把该包导出到你的模块:
--add-exports java.desktop/com.sun.imageio.plugins.jpeg=ir.mehritco.megnatis.faststonecapture
- IDE运行时:在运行配置的「VM options」中添加该参数
- 打包后运行:将参数追加到
java -jar命令后
⚠️ 注意:此方法依赖Java内部API,未来JDK版本可能移除或修改该包,存在兼容性风险。
方法二:改用标准IIOMetadata API(推荐)
为避免依赖内部API,直接使用IIOMetadata的标准方法实现元数据操作,无需强制转换为JPEGMetadata。修改代码如下:
// 替换原代码中JPEGMetadata相关逻辑 IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize"); horiz.setAttribute("value", Double.toString(getDpi())); IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize"); vert.setAttribute("value", Double.toString(getDpi())); IIOMetadataNode dim = new IIOMetadataNode("Dimension"); dim.appendChild(horiz); dim.appendChild(vert); // 直接调用IIOMetadata的mergeTree方法 metadata.mergeTree("javax_imageio_jpeg_image_1.0", dim);
这种方式完全基于公开标准API,能保证代码在未来JDK版本的兼容性。
问题根源
Java模块化系统中,java.desktop仅对外导出公开API包(如javax.imageio),com.sun.*开头的包属于内部实现,默认不对外暴露。即使模块声明中添加了requires java.desktop;,也只能访问该模块的公开API,无法直接访问内部私有包。
内容的提问来源于stack exchange,提问作者FarHooD
相关产品推荐
相关产品推荐

