对于刚刚将应用程序移植到较新的 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 中吗?
如果您要生成可执行 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 版本之间更好的可移植性。
您可以使用 burningwave core 的 Modules#exportAllToAll 来避免添加任何
--add-opens
参数。
做法如下:
AccessibleObject#override
的字段偏移量(java17中为12)。Unsafe
和override
的场偏移来执行setAccessible
。MethodHandles.Lookup
的构造函数参数并执行setAccessible
。MethodHandles.Lookup
对象访问任何私有方法和字段。Class#getDeclaredMethods0
和 Class#getDeclaredFields0
替换反射。java.lang.Module
和java.lang.ModuleLayer
以实现exportAllToAll
。