如果 jar 文件具有 L 属性/重解析点,为什么 Java 应用程序无法在 Windows 上运行

问题描述

我真的希望以下内容能在我们的想法用完时向某人敲响警钟。非常感谢您提供有关如何进一步诊断的答案或建议。

我们有一个 Java 应用程序,它已经运行了 18 个月没有问题。它现在正在迁移到运行 Windows Server 2019 Standard 作为 VM 的新平台。 在第一次安装时,一切正常运行,但应用程序有时无法启动,只能通过重新复制所有 jar 文件来修复。这是暂时的,因为最终它会再次失败。

经过大量监控,我们注意到有一个 Windows 进程会定期在所有文件上设置“L”文件属性并创建重新解析数据。这应该不是问题,但是一旦发生这种情况,JVM 将无法启动应用程序。 (任何 Windows 高手都知道这是做什么的?)

一个关键点是通过指定 JPMS 参数来启动应用程序,例如:

.fla

这运行良好,在 jar 文件上设置了“L”属性,然后失败并显示消息:

git lfs

将 MyApp.jar 重命名为其他名称,然后将其复制回 MyApp.jar 可以解决问题,因为它会创建一个没有 L 属性和重新解析数据的文件(直到进程重新应用它)

此行为不仅适用于这一操作,还适用于使用模块系统的任何地方,例如:

java -p MyApp.jar;MyApp_mods -m  mymodule/mypackage.StartGUI

有趣的是(!),如果我们尝试一个更简单的非模块化应用程序并运行:

Error occurred during initialization of boot layer
java.lang.module.FindException: Module format not recognized: MyApp.jar

那么即使设置了 L 属性,应用程序也能正常运行。

显然我们并不完全理解,但看起来好像通过模块系统运行以某种方式意味着无法读取具有 L 属性/重新解析数据的文件(?)

我们已经尝试了各种版本的 OpenJDK 热点和 OpenJ9 JVM,但结果相同。有什么想法吗?

解决方法

这只是部分答案,但值得展示,以防有人遇到同样的问题。当有更多信息时,我会尝试更新,但可能需要一段时间。 (21 年 4 月 19 日更新 - 报告了错误。请参阅 JDK-8265439

正如 Naman 所指出的,问题在于在 .jar 文件中查找模块信息的 JPMS 代码。该代码的一部分获取文件属性并检查 attr.isRegularFile()。如果这是 false,则抛出 java.lang.module.FindException: Module format not recognized

每当 Windows 文件管理进程运行时,它都会创建一个重新分析点并在文件上设置 L 属性。在此之后,attr.isRegularFile() 返回 false。

我不确定这个过程到底是什么,但微软重新分析标签 0x9000601A 的文档是: IO_REPARSE_TAG_CLOUD_6 - Used by the Cloud Files filter,for files managed by a sync engine such as OneDrive. Server-side interpretation only,not meaningful over the wire.

在 Java 中,BasicFileAttributes 类由 sun.nio.fs.WindowsFileAttributes 为 Windows 实现。对源代码的检查确认,如果在文件属性中设置了 isRegularFile() 位,FILE_ATTRIBUTE_REPARSE_POINT 将返回 false。

如果从类路径加载 .jar 文件,这些都不会导致问题,所以这是解决方法 - 不要使用 JPMS 运行。花了一个月的时间对应用程序进行模块化,这并不理想,但目前可以使用。

我认为这一定是 JPMS 中的一个错误,因为 .jar 文件可以通过类路径而不是从模块路径加载是没有意义的。我会收集更多信息并报告它,尽管复制它可能很困难。

感谢您的回复 - 他们都提供了帮助。

,

我想这是一个错误。

NTFS 文件系统使用 Reparse Point 属性来实现符号链接、实现挂载点和实现其他文件系统技术,例如将较少使用的文件自动移动到长期存储区域(压缩文件/文件系统)/或设备(例如磁带) ).

“重解析点和扩展属性是互斥的。当文件包含扩展属性时,NTFS 文件系统不能创建重解析点,也不能在包含重解析点的文件上创建扩展属性。”

因此,解决方法是在文件中设置扩展属性以禁止此行为/错误。

PS 我猜您的 Windows Server 运行某种“自动压缩/移动较少使用的文件”服务,请尽可能停用此服务。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...