Aparapi执行报错:无法访问字段,模块权限问题求助
问题
开发环境:IntelliJ IDEA + Maven,无GPU笔记本,使用Aparapi 3.0.0框架(无GPU时默认用ThreadPool替代)。运行官方Add示例代码时,执行kernel.execute(Range.create(size))抛出权限错误,错误信息如下:
Jun 01, 2023 2:12:07 PM com.aparapi.internal.model.ClassModel$AttributePool <init> WARNING: Found unexpected Attribute (name = NestHost) java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:465) at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1082) Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field final float[] com.potato.ray_casting_maven.App$1.val$sum accessible: module com.potato.ray_casting_maven does not "opens com.potato.ray_casting_maven" to module aparapi at 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.Field.setAccessible(Field.java:172) at aparapi@3.0.0/com.aparapi.internal.kernel.KernelRunner.executeInternalInner(KernelRunner.java:1731) at aparapi@3.0.0/com.aparapi.internal.kernel.KernelRunner.executeInternalOuter(KernelRunner.java:1471) at aparapi@3.0.0/com.aparapi.internal.kernel.KernelRunner.execute(KernelRunner.java:1454) at aparapi@3.0.0/com.aparapi.Kernel.execute(Kernel.java:2907) at aparapi@3.0.0/com.aparapi.Kernel.execute(Kernel.java:2864) at aparapi@3.0.0/com.aparapi.Kernel.execute(Kernel.java:2804) at com.potato.ray_casting_maven/com.potato.ray_casting_maven.App.main(App.java:50) ... 11 more Exception running application com.potato.ray_casting_maven.App WARNING: Aparapi is running on an untested OpenCL platform version: OpenCL 3.0
当前module-info.java配置:
module com.potato.ray_casting_maven { requires javafx.controls; requires javafx.fxml; requires aparapi; requires aparapi.jni; opens com.potato.ray_casting_maven to javafx.fxml; exports com.potato.ray_casting_maven; }
pom.xml关键依赖:
<dependency> <groupId>com.aparapi</groupId> <artifactId>aparapi</artifactId> <version>3.0.0</version> </dependency>
尝试添加opens com.potato.ray_casting_maven to aparapi;时IDE无法识别aparapi模块;使用kernel.run()可运行但仅执行单实例,无法实现并行。
解决方案
1. 修正module-info.java的模块配置
IDE无法识别aparapi是因为模块名称错误,Aparapi的官方模块ID是com.aparapi而非aparapi。修改后的module-info.java:
module com.potato.ray_casting_maven { requires javafx.controls; requires javafx.fxml; requires com.aparapi; requires com.aparapi.jni; opens com.potato.ray_casting_maven to javafx.fxml, com.aparapi; exports com.potato.ray_casting_maven; }
- 将
requires aparapi;改为requires com.aparapi;,requires aparapi.jni;改为requires com.aparapi.jni; - 在
opens语句中添加com.aparapi,允许Aparapi框架通过反射访问模块内部字段
2. 显式指定CPU执行模式(无GPU场景)
修正模块配置后,可强制Aparapi使用CPU线程池模式,避免OpenCL相关逻辑干扰:
- 方式一:在JVM启动参数中添加:
-Dcom.aparapi.executionMode=CPU - 方式二:在代码中提前设置:
Kernel.setExecutionMode(Kernel.EXECUTION_MODE.CPU);
3. 替换匿名内部类为静态内部类/顶级类
错误中的App$1说明使用了匿名内部类实现Kernel,嵌套类的字段反射访问更容易触发权限问题。建议将Kernel实现为静态内部类或独立顶级类:
public static class AddKernel extends Kernel { private final float[] a; private final float[] b; private final float[] sum; public AddKernel(float[] a, float[] b, float[] sum) { this.a = a; this.b = b; this.sum = sum; } @Override public void run() { int i = getGlobalId(); sum[i] = a[i] + b[i]; } }
主代码中实例化执行:
AddKernel kernel = new AddKernel(a, b, sum); kernel.execute(Range.create(size));
内容的提问来源于stack exchange,提问作者potatosaregreat
相关产品推荐
相关产品推荐

