是否可以继承对匿名子模块的反射访问?
Is it possible to inherit reflective access to anonymous child module?
假设我写了一个名为 mylib
的 module/library,它使用了一个名为 internal
的 internal/hidden 第三方 module/library。 mylib 的 API 不公开第三方库的任何功能,在不久的将来可能会被其他东西取代。
module mylib {
requires internal;
exports some.pgk.from.mylib;
}
但这就是我的问题。内部库需要对通过 mylib 的 public API 传递的 classes/objects 的反射访问来完成它的工作。
名为 app
的示例 application/module 使用我的库必须定义以下 moduleinfo.java
module app {
requires mylib;
opens some.pkg.from.app to internal;
}
但这很糟糕,因为它向我的库的用户公开了内部使用的模块,如果不破坏 app[=,我以后将无法 remove/change 它31=]。理想情况下,我希望允许模块 internal 反射访问所有对 mylib 开放的模块:
module app {
requires mylib;
opens some.pkg.from.app to mylib; // also open to internal without naming it
}
这可以用当前的 (Java 17) 模块系统来完成吗?如果这不可能,是否有好的解决方法?
我看到四种可能的解决方案:
从 mylib
呼叫 appModule.addOpens("some.pkg.from.app", internalModule)
。
If this module has opened a package to at least the caller module then update this module to open the package to the given module.
这是有效的,因为 myapp
已经打开包 some.pkg.from.app
到 mylib
模块 - 这是调用者模块。
您必须为已打开到您的模块的每个包重复它。
如果你不处理模块层,你可以反射性地枚举所有对你的模块开放的包。
如果您必须处理层 - 您必须枚举所有层 - 并且可以在运行时添加这些层。
将 Consumer<AccessibleObject> makeAccessible = ao -> ao.setAccessible(true);
传递给 internal
。
这是可行的,因为 setAccessible
的调用者现在是 mylib
。
(或者 myapp
,如果消费者来自那里。)
将 mylib
的完整权限 lookup 传递给 internal
。
您可以使用此 Lookup 调用 AccessibleObject.setAccessible
。
或者做点别的,比如调用 Module.addOpens
.
将完整权限查找从 myapp
传递到 mylib
,后者又将其传递到 internal
。
这里的好处是您无需声明打开包 - 因为通过传递的查找查找的任何 MethodHandle
都将像从 myapp
中调用一样工作。
您甚至可以限制此查找。
假设我写了一个名为 mylib
的 module/library,它使用了一个名为 internal
的 internal/hidden 第三方 module/library。 mylib 的 API 不公开第三方库的任何功能,在不久的将来可能会被其他东西取代。
module mylib {
requires internal;
exports some.pgk.from.mylib;
}
但这就是我的问题。内部库需要对通过 mylib 的 public API 传递的 classes/objects 的反射访问来完成它的工作。
名为 app
的示例 application/module 使用我的库必须定义以下 moduleinfo.java
module app {
requires mylib;
opens some.pkg.from.app to internal;
}
但这很糟糕,因为它向我的库的用户公开了内部使用的模块,如果不破坏 app[=,我以后将无法 remove/change 它31=]。理想情况下,我希望允许模块 internal 反射访问所有对 mylib 开放的模块:
module app {
requires mylib;
opens some.pkg.from.app to mylib; // also open to internal without naming it
}
这可以用当前的 (Java 17) 模块系统来完成吗?如果这不可能,是否有好的解决方法?
我看到四种可能的解决方案:
从
mylib
呼叫appModule.addOpens("some.pkg.from.app", internalModule)
。If this module has opened a package to at least the caller module then update this module to open the package to the given module.
这是有效的,因为
myapp
已经打开包some.pkg.from.app
到mylib
模块 - 这是调用者模块。
您必须为已打开到您的模块的每个包重复它。
如果你不处理模块层,你可以反射性地枚举所有对你的模块开放的包。
如果您必须处理层 - 您必须枚举所有层 - 并且可以在运行时添加这些层。将
Consumer<AccessibleObject> makeAccessible = ao -> ao.setAccessible(true);
传递给internal
。这是可行的,因为
setAccessible
的调用者现在是mylib
。
(或者myapp
,如果消费者来自那里。)将
mylib
的完整权限 lookup 传递给internal
。您可以使用此 Lookup 调用
AccessibleObject.setAccessible
。
或者做点别的,比如调用Module.addOpens
.将完整权限查找从
myapp
传递到mylib
,后者又将其传递到internal
。这里的好处是您无需声明打开包 - 因为通过传递的查找查找的任何
MethodHandle
都将像从myapp
中调用一样工作。
您甚至可以限制此查找。