[spring-projects/spring-boot]修复插件时区依赖性

2024-05-08 732 views

回答

2

我在本地安装了这个版本的插件,然后当我在复制项目中使用该版本时,我实际上得到了正确的时间戳,并且所有文件(使用 docker 中的所有时区)都是二进制相同的,并且时间戳看起来与配置的完全相同:2011- 11-11 22:22 。

https://github.com/nielsbasjes/BugreportSpringPluginTimezone

5

@nielsbasjes 我不认为像这样操纵时区是解决问题的正确方法。

查看.jar.original复制示例中的文件,相同的时间戳应用于两个 jar,与本地时区无关。所以 Maven 正在做正确的事情。 Maven用来解析的代码project.build.outputTimeStamp在这里:https://github.com/apache/maven-archiver/blob/maven-archiver-3.6.0/src/main/java/org/apache/maven/archiver/MavenArchiver .java#L886-L887

与 Maven 不同,Spring Boot在解析日期withOffsetSameInstant(ZoneOffset.UTC)后不会应用修饰符: https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-tools/spring -boot-maven-plugin/src/main/java/org/springframework/boot/maven/RepackageMojo.java#L238。如果应用此修改器可以解决问题,那么对我来说它看起来是一个更干净的解决方案。OffsetDateTime.parse(outputTimeStamp)

您想尝试一下这个改变吗?

1

问题不在于时间戳的解析。这样做是正确的。时区是提供的时间戳的一部分(在我的示例中为“Z”)并且已正确处理。

然后,解析的时间戳被保存在一个实例中,该实例java.nio.file.attribute.FileTime将时间戳本质上存储为纪元(即没有任何时区)。

该提议withOffsetSameInstant(ZoneOffset.UTC)并未解决此问题,因为这不会更改复制到 FileTime 实例中的基础纪元值。

然后,Zip 创建代码(来自 commons-compress)使用基于系统默认时区的 Calendar 实例将纪元转换为其他内容。

据我所知,Spring 项目中的所有代码都正确处理了时间戳。

2

另外:可以提供所需的时间戳作为纪元,但纪元不能有时间戳,因此必须选择时区。当前的选择是本地系统时区,我的建议是强制(或可配置?)将其设置为 UTC 时区。

5

@philwebb所以您使用当前时区来移动纪元时间戳,因为您希望底层代码将其再次移回?我会投票反对这样的代码。

5

是的。我更喜欢它的原因是因为TimeZone.setDefault(...)更改了整个 JVM 的默认时区。如果 Maven 在另一个线程中(现在或将来)做其他事情,那么默认时区可能会在它的脚下发生变化。

4

TimeZone.setDefault(...)更改整个 JVM 的默认时区

这也是我担心的,这可能会产生难以诊断的不可预测的副作用。

6

是的,确实如此。也许将此插件标记为非线程安全?

7

明天我会看看是否能让这个令人讨厌的时移工作变得可靠。说到时区..这里已经是明天了...

8

我发现 javadoc 比setTime更好,setLastModifiedTime并且实际上描述了在写入值时使用默认时区。我已经改用这种方法并采用了转变方法。该修复位于提交 998d59b7ac1a75b26634e4fd2843a7833e554840 中。

感谢您提出问题并提供分析。