Java模块化代理反射报错:jdk.proxy2未导出包至自定义模块
Java模块化下反射调用代理对象报错的原因解析
错误含义
这个IllegalAccessException的核心是模块权限拦截:你的模块ca.example.MyStore试图访问JDK代理模块jdk.proxy2中的自动生成代理类com.sun.proxy.jdk.proxy2.$Proxy10,但jdk.proxy2并未将该内部包导出给你的模块,导致跨模块反射访问被禁止。
深层原因
- 代理类的归属变更:Java 16及以后版本中,
Proxy.newProxyInstance生成的动态代理类不再属于应用模块,而是归属于JDK内置的jdk.proxy2模块,且其所在的com.sun.proxy.jdk.proxy2是内部私有包,默认不会对任何应用模块开放导出权限。 - 跨模块反射的权限规则:Java模块系统的权限检查是跨模块生效的——哪怕你的反射代码写在自己模块内部,只要访问的是其他模块的非导出类/成员,就会被拦截。你代码中
proxy.getClass().getMethod("itemDiscount")、method.invoke(proxy)的操作,本质是在ca.example.MyStore模块中反射访问jdk.proxy2模块的内部类成员,违反了默认的权限规则。 - open模块的权限放宽:将模块标记为
open后,JVM会允许该模块内的反射代码绕过模块系统的导出检查,访问任意模块的内部类和成员,因此代理类的方法调用能正常执行。
补充说明
代码中使用的InvocationHandler.invokeDefault是Java 16新增的API,专门用于调用接口默认方法,但这个操作本身依赖于代理类能正常被反射访问——而模块权限拦截恰好阻断了这个访问路径,所以必须通过open module来绕过限制。
内容的提问来源于stack exchange,提问作者timmy
相关产品推荐
相关产品推荐

