I'm trying to enable https://maven.apache.org/guides/mini/guide-reproducible-builds.html for my springboot project.

I'm using maven-git-version-extension. And found that springboot can't handle seconds,

Caused by: java.time.format.DateTimeParseException: Text '1729757074' could not be parsed at index 0
    at java.time.format.DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:2052)
    at java.time.format.DateTimeFormatter.parse (DateTimeFormatter.java:1954)
    at java.time.Instant.parse (Instant.java:397)
    at org.springframework.boot.maven.BuildInfoMojo.getBuildTime (BuildInfoMojo.java:157)
    at org.springframework.boot.maven.BuildInfoMojo.getProjectDetails (BuildInfoMojo.java:131)
    at org.springframework.boot.maven.BuildInfoMojo.execute (BuildInfoMojo.java:114)

See for details https://github.com/qoomon/maven-git-versioning-extension/issues/340.

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/BuildInfoMojo.java#L149

A alternative round of parsing for the epoch seconds would be an improvement.

Comment From: wilkinsona

We document time as "the value used for the build.time property in a form suitable for Instant#parse(CharSequence)" so, on the one hand this is working as designed. On the other hand, we document that it defaults to ${project.build.outputTimestamp} and the spec isn't clear that ISO-8601 is the only valid format as it says "with an ISO 8601 formatted date+time" in one place but also shows an example that supports both ISO 8601 and seconds since the epoch. On balance, I think it's worth us adding a fallback to try seconds since the epoch if parsing as ISO 8601 fails.

Comment From: ahoehma

I would like to provide a fix for this? If this is okay for you? I already forked springboot.

Comment From: wilkinsona

Yes, please. That'd be great. Please let us know if you have any questions about contributing.

Comment From: ahoehma

@wilkinsona does it make sense to reuse org.springframework.boot.maven.MavenBuildOutputTimestamp inside org.springframework.boot.maven.BuildInfoMojo? Because then the support for epoch seconds will be automatically :)

Comment From: philwebb

@ahoehma We could try that approach if there's reusable code. We might need to rename that class, but it's package private so that's not a problem. We can take care of that part later if necessary.

Comment From: ahoehma

@philwebb exactly :-) From my point of view the MavenBuildOutputTimestamp have already a good name.

Comment From: ahoehma

I need some more help ... not for the fix itself ... but for the eclipse / gradle setup :-)

I followed the eclipse installation steps ... and for the first time everything worked fine. I had all the spring boot projects up and running (no problems) in a brand new eclipse installation (I' using 2024-09 instead of 2021-03 which is the current suggested version in https://github.com/spring-projects/spring-boot/wiki/Working-with-the-Code#importing-into-eclipse).

But today ... all the projects are red and have thousands of compiler errors and I don't know why.

Gradle output looks fine to me:

Working Directory: D:\Dev\git\privat\spring-boot
Gradle user home: D:\Dev\gradle_stuff
Gradle Distribution: Gradle wrapper from target build
Gradle Version: 8.10.2
Java Home: D:\Dev\Java\jdk-17.0.4
JVM Arguments: None
Program Arguments: None
Build Scans Enabled: false
Offline Mode Enabled: false
> Task :buildSrc:compileJava UP-TO-DATE
> Task :buildSrc:compileGroovy NO-SOURCE
> Task :buildSrc:pluginDescriptors UP-TO-DATE
> Task :buildSrc:processResources UP-TO-DATE
> Task :buildSrc:classes UP-TO-DATE
> Task :buildSrc:jar UP-TO-DATE
> Task :spring-boot-system-tests:spring-boot-deployment-tests:cleanEclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-static:cleanEclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-jetty-jsp:cleanEclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-traditional:cleanEclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-jsp:cleanEclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-servlet:cleanEclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-tomcat-jsp:cleanEclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-war:cleanEclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-servlet:cleanEclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-jetty-jsp:cleanEclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-war:cleanEclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-tomcat-jsp:cleanEclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-traditional:cleanEclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-tomcat-jsp:cleanEclipseWtp UP-TO-DATE
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-static:cleanEclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-servlet:cleanEclipseWtp UP-TO-DATE
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-static:cleanEclipseWtp UP-TO-DATE
> Task :spring-boot-system-tests:spring-boot-deployment-tests:cleanEclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-jsp:cleanEclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-traditional:cleanEclipseWtp UP-TO-DATE
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-jetty-jsp:cleanEclipseWtp UP-TO-DATE
> Task :spring-boot-system-tests:spring-boot-deployment-tests:cleanEclipseWtp UP-TO-DATE
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-jsp:cleanEclipseWtp UP-TO-DATE
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-war:cleanEclipseWtp UP-TO-DATE
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-servlet:eclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-tomcat-jsp:eclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-static:eclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-war:eclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-jetty-jsp:eclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-jsp:eclipseWtpComponent
> Task :spring-boot-system-tests:spring-boot-deployment-tests:eclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-static:eclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-static:eclipseWtp
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-war:eclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-servlet:eclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-jetty-jsp:eclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-servlet:eclipseWtp
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-jetty-jsp:eclipseWtp
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-war:eclipseWtp
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-jsp:eclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-web-jsp:eclipseWtp
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-tomcat-jsp:eclipseWtpFacet
> Task :spring-boot-system-tests:spring-boot-deployment-tests:eclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-tomcat-jsp:eclipseWtp
> Task :spring-boot-system-tests:spring-boot-deployment-tests:eclipseWtp
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-traditional:eclipseWtpComponent
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-traditional:eclipseWtpFacet
> Task :spring-boot-tests:spring-boot-smoke-tests:spring-boot-smoke-test-traditional:eclipseWtp

BUILD SUCCESSFUL in 17s
44 actionable tasks: 32 executed, 12 up-to-date
> Task :buildSrc:compileJava UP-TO-DATE
> Task :buildSrc:compileGroovy NO-SOURCE
> Task :buildSrc:pluginDescriptors UP-TO-DATE
> Task :buildSrc:processResources UP-TO-DATE
> Task :buildSrc:classes UP-TO-DATE
> Task :buildSrc:jar UP-TO-DATE

CONFIGURE SUCCESSFUL in 41s
4 actionable tasks: 4 up-to-date

SpringBoot build-info doesn't support seconds since the epoch from project.build.outputTimestamp

Is there anything I missed?

Comment From: ahoehma

Hmmm ... I re-started the eclipse ... (did something - cleaned all projects I guess - can't remember) - and now ALL projects are fine (like after the initial import) - and now ONLY the "buildSrc" shows compiler errors:

SpringBoot build-info doesn't support seconds since the epoch from project.build.outputTimestamp

Comment From: wilkinsona

Sorry for the trouble with Eclipse. The buildSrc thing is due to JPMS, split packages, and how Buildship configures the project on import. See https://github.com/spring-projects/spring-boot/issues/41285 for a manual fix that we hope to make automatic.

Comment From: ahoehma

NP. Thanks for the info.

Comment From: wilkinsona

Closing in favor of #42922. Thanks for the PR, @ahoehma.