java - 是否可以继承对匿名子模块的反射访问?

标签 java reflection java-platform-module-system java-17

假设我编写了一个名为 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)模块系统来完成吗?万一这不可能,有没有好的解决方法?

最佳答案

我看到四种可能的解决方案:

  1. 调用 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.appmylib module - 这是调用者模块。
    您必须对模块打开的每个包重复此操作。
    如果您不处理模块层,您可以反射枚举对您的模块开放的所有包。
    如果您必须处理层 - 您必须枚举所有层 - 并且可以在运行时添加这些层。

  2. 通过 Consumer<AccessibleObject> makeAccessible = ao -> ao.setAccessible(true);internal .

    这有效,因为现在 setAccessible 的调用者现在是mylib .
    (或者 myapp ,如果消费者来自那里。)

  3. 传递完整权限lookup来自mylibinternal .

    您可以使用这个Lookup调用AccessibleObject.setAccessible .
    或者也许做其他事情,比如打电话 Module.addOpens .

  4. 传递来自 myapp 的完整权限查找至mylib ,然后将其传递给 internal .

    这样做的好处是您不需要声明您打开了一个包裹 - 任何MethodHandle您通过传递的查找进行查找将像从 myapp 调用它一样工作。 .
    您甚至可以限制此查找。

关于java - 是否可以继承对匿名子模块的反射访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69728262/

相关文章:

java - Java平台模块系统中的 'java.se'和 'java.base'模块有什么区别

java - 如何将 GUI 对象放置在 GridBagLayout 内单元格内的特定 x/y 位置

java - 在 Apache Karaf 下设置 Java 堆大小

asp.net - 在 bin 文件夹外的 ASP.NET 项目中解析程序集

android - 如何检测通知面板是否展开?

java - 如何在Java模块中使模块私有(private)方法

java - 模块 java.base 不读取模块 java.desktop

java - JsonPath : filter by value in array

java - RSS 中的 CDATA 部分不起作用 - rometools

c# - 使用反射获取继承接口(interface)的类的属性