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

我真的希望以下几点钟声能给我们一个铃声,因为我们的想法已经用完了。有关如何进一步诊断的答案或建议将不胜感激。

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

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

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

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

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

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

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

此行为不仅适用于此操作,还适用于使用模块系统的任何位置,例如:

 java --list-modules any-jar-in-the-app.jar    

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

java -jar MySimpleApp.jar

然后,即使设置了 L 属性,应用也能正常运行。

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

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


答案 1

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

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

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

我不确定该过程到底是什么,但0x9000601A重新解析标记的Microsoft文档是: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 由 Windows 实现。检查源确认,如果在文件属性中设置了位,则将返回 false。sun.nio.fs.WindowsFileAttributesisRegularFile()FILE_ATTRIBUTE_REPARSE_POINT

如果从类路径加载.jar文件,则这些都不会导致问题,因此这是解决方法 - 不要使用JPMS运行。花了一个月的时间模块化应用程序,这并不理想,但它现在有效。

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

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


答案 2

我想这是一个错误。

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

“重新分析点和扩展属性是相互排斥的。当文件包含扩展属性时,NTFS 文件系统无法创建重新分析点,并且无法在包含重新分析点的文件上创建扩展属性。

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

PS:我猜你的Windows服务器运行某种“自动压缩/移动较少使用的文件”服务,如果可能的话,请停用此服务。


推荐