假设我编写了一个名为 mylib
的模块/库,它使用名为 internal
的内部/隐藏第三方模块/库。 mylib 的 API 不会公开该第三方库的任何功能,并且在不久的将来可能会被其他库所取代。
module mylib {
requires internal;
exports some.pgk.from.mylib;
}
但这是我的问题。内部库需要对通过 mylib 的公共(public) API 传递的类/对象进行反射访问才能完成工作。
使用我的库的名为 app
的示例应用程序/模块必须定义以下 moduleinfo.java
module app {
requires mylib;
opens some.pkg.from.app to internal;
}
但这很糟糕,因为它向我的库的用户公开了内部使用的模块,并且我将来无法在不破坏应用程序的情况下删除/更改它。理想情况下,我希望允许模块内部反射访问对mylib开放的所有模块:
module app {
requires mylib;
opens some.pkg.from.app to mylib; // also open to internal without naming it
}
这可以通过当前(Java 17)模块系统来完成吗?万一这不可能,有没有好的解决方法?
最佳答案
我看到四种可能的解决方案:
调用
appModule.addOpens("some.pkg.from.app", internalModule)
来自mylib
.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
module - 这是调用者模块。
您必须对模块打开的每个包重复此操作。
如果您不处理模块层,您可以反射枚举对您的模块开放的所有包。
如果您必须处理层 - 您必须枚举所有层 - 并且可以在运行时添加这些层。通过
Consumer<AccessibleObject> makeAccessible = ao -> ao.setAccessible(true);
至internal
.这有效,因为现在
setAccessible
的调用者现在是mylib
.
(或者myapp
,如果消费者来自那里。)传递完整权限lookup来自
mylib
至internal
.您可以使用这个Lookup调用
AccessibleObject.setAccessible
.
或者也许做其他事情,比如打电话Module.addOpens
.传递来自
myapp
的完整权限查找至mylib
,然后将其传递给internal
.这样做的好处是您不需要声明您打开了一个包裹 - 任何
MethodHandle
您通过传递的查找进行查找将像从myapp
调用它一样工作。 .
您甚至可以限制此查找。
关于java - 是否可以继承对匿名子模块的反射访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69728262/