JavaFX Media对象无法工作,报javafx.graphics导出权限错误如何解决?
问题重现
尝试通过以下代码实现音频播放:
public void playSound (){ Media media = new Media(new File(audioFile).toURI().toString()); MediaPlayer mediaPlayer = new MediaPlayer(media); mediaPlayer.setCycleCount(MediaPlayer.INDEFINITE); mediaPlayer.play(); }
音频文件路径示例:
this.audioFile = "C:\\(...)\\Pomodoro\\src\\Sounds\\calm.wav";
调用该方法时,实例化Media对象抛出错误:
Exception in thread "JavaFX Application Thread" java.lang.IllegalAccessError: class com.sun.media.jfxmediaimpl.NativeMediaManager (in unnamed module @0x2e23a125) cannot access class com.sun.glass.utils.NativeLibLoader (in module javafx.graphics) because module javafx.graphics does not export com.sun.glass.utils to unnamed module @0x2e23a125
环境:JavaFX SDK 20.0.1 + Java JDK 19,已尝试添加VM参数--add-exports javafx.graphics/com.sun.glass.utils=ALL-UNNAMED但问题未解决。
解决方案
1. 对齐JDK与JavaFX版本
JavaFX与JDK版本不匹配是引发此类模块访问错误的常见原因。当前使用JDK19搭配JavaFX20,版本不一致会导致内部模块依赖冲突。
- 处理方式:将JDK升级到20,或把JavaFX降级到19,确保两者版本完全一致。
2. 添加完整的VM参数
仅添加单个--add-exports不足以覆盖媒体模块的所有内部访问需求,需补充以下参数到VM运行配置中:
--add-exports javafx.graphics/com.sun.glass.utils=ALL-UNNAMED --add-exports javafx.media/com.sun.media.jfxmediaimpl=ALL-UNNAMED --add-opens javafx.graphics/com.sun.glass.utils=ALL-UNNAMED --add-opens javafx.media/com.sun.media.jfxmediaimpl=ALL-UNNAMED
--add-opens用于允许运行时访问模块的包,部分JavaFX内部实现需要此权限。
3. 采用模块化项目结构(推荐)
相比添加临时的VM参数,更规范的方式是将项目转为模块化:
- 在项目根目录创建
module-info.java,内容如下:
module Pomodoro { requires javafx.controls; requires javafx.media; opens your.package.name to javafx.graphics, javafx.media; // 替换为你的主类所在包 }
- 确保IDE或构建工具(如Maven/Gradle)正确识别模块配置,运行时无需额外添加
--add-exports类参数。
4. 验证音频文件路径有效性
虽然当前错误与路径无关,但后续可通过以下代码确认文件是否存在:
File soundFile = new File(audioFile); if (!soundFile.exists()) { System.err.println("音频文件不存在:" + audioFile); return; }
内容的提问来源于stack exchange,提问作者Nichlas Andersson

