对于刚刚将应用程序移植到较新的 Java 的应用程序,是否有 --add-opens 命令行参数的替代方案?

问题描述 投票:0回答:2

对于刚刚将应用程序移植到较新的 Java 的应用程序,是否有替代 --add-opens 命令行参数的方法?

为了使我们古老的单体应用程序能够在 Java 11 和 Java 17 上运行,我必须添加几个 --add-opens。我想暂时保持应用程序非模块化/整体式。

为了使其运行,我必须在我们已经很长的 VM 参数列表中添加相当长的 --add-opens 列表。示例:

--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED
--add-opens java.base/java.io=ALL-UNNAMED
--add-opens java.base/java.text=ALL-UNNAMED
--add-opens java.base/java.time=ALL-UNNAMED
--add-opens java.desktop/java.awt=ALL-UNNAMED
--add-opens java.desktop/java.swing=ALL-UNNAMED
--add-opens java.desktop/java.swing.table=ALL-UNNAMED
--add-opens java.desktop/java.swing.plaf.basic=ALL-UNNAMED
...

这样的例子不胜枚举。它有效,但很笨拙。我们已经有许多命令行参数、VM 和程序参数。恐怕我们会在某个时刻达到 CLI 限制。所有这些参数也使得从 IDE 启动应用程序变得更加繁琐。

还有其他选择吗?
我有类似 module-info.java 文件来全局声明非模块化项目的空缺吗?我可以将文件保留在项目中、生成的 JAR 中吗?

java java-11 java-17 java-module
2个回答
4
投票

如果您要生成可执行 jar 文件,则可以使用

Add-Opens
清单属性。使用
java -jar <jar file>
运行应用程序时,应避免传递所有标志。请参阅:https://openjdk.org/jeps/261#Packaging:-Modular-JAR-files

java
可执行文件还支持使用
@
从文件扩展命令行标志:

java @options org.main.Main

options
文件中的行将被“扩展”到命令行中。因此,您可以将所需的选项放入添加到项目的文件中,然后与
@
一起使用。我不确定您的 IDE 是否支持(不过,您也可以将 IDE 运行配置检查到项目中)。

一般来说,您应该尝试减少对 JDK 内部的反射访问,以便您一开始就不需要这些标志。这也将为您提供 JDK 版本之间更好的可移植性。


0
投票

您可以使用 burningwave coreModules#exportAllToAll 来避免添加任何

--add-opens
参数。

做法如下:

  1. 找到
    AccessibleObject#override
    的字段偏移量(java17中为12)。
  2. 使用
    Unsafe
    override
    的场偏移来执行
    setAccessible
  3. 获取
    MethodHandles.Lookup
    的构造函数参数并执行
    setAccessible
  4. 使用最高权限
    MethodHandles.Lookup
    对象访问任何私有方法和字段。
  5. 使用私有
    Class#getDeclaredMethods0
    Class#getDeclaredFields0
    替换反射。
  6. 修改
    java.lang.Module
    java.lang.ModuleLayer
    以实现
    exportAllToAll
© www.soinside.com 2019 - 2024. All rights reserved.