New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maven build generates consistent output #1211
Maven build generates consistent output #1211
Conversation
Set build output timestamp per: https://maven.apache.org/guides/mini/guide-reproducible-builds.html
It's an interesting point, but I'm not sure we need a reproducible build for petclinic (and a hard-coded timestamp wouldn't be the best way to achieve it, IMO). |
Sure, you don't absolutely need it.
I worked on it very hard, and I can tell you that surprisingly it is. When people will use Maven Build Cache extensively in the future, the impact will be visible.
see https://maven.apache.org/guides/mini/guide-reproducible-builds.html#faq for a summary on value update strategies: if you have a new idea, I'm very much interested I should definitively submit a talk to Devoxx UK next year, and in fact every Devoxx, to spread the word: too late for this year, I'll be there only as attendee... |
There are open issues linked to in the wiki (https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=74682318). Note: I can see that probably most are fixed (although I was initially confused by the notation in the table). I do think reproducible builds are a good idea, but it seems to be a bit of an evolving standard for Maven, so I'm not convinced we should take the dependency. Also I don't understand how a hard-coded property in pom.xml fixes anything - it's just going to be stale every time someone makes a change and forgets to update the timestamp.
I don't think I know what that is, and it isn't referenced in any of the links you posted (as far as I could tell). |
The Maven Build Cache is an extension that adds caching to Maven builds. This works similarly to how local and remote caching works with Gradle builds and is compatible with other remote build caches (e.g. ge.spring.io) The "hard-coded" property is similar to how other maven properties work, for example, if you set a dependency version as a property, it's hardcoded until someone or some automated process updates them (e.g. Dependabot). This timestamp is used as the date in the table of contents of archive files (jars). When this property is not set, jars with identical contents would produce a different checksum. NOTE: This property could also be epoch seconds (instead of a ISO-8601 formatted date), which may cause less confusion or at least more likely to be overlooked. I can also update this PR with a comment too, if you think that would help! Just let me know! |
A version property can be hard-coded because it's meaning is clear. Hard-coding a timestamp that is supposed to represent the state of the source code makes no sense at all to me - it seems like little more than a hack - it will always be wrong or misleading. I didn't see any features in the versions plugin that would help to update it. Maybe I need to see a complete example where the property value is actually updated in a sensible way? |
now, if you find a new strategy to get a reproducible zip, please share: I'm all ears open |
I can see the behaviour you implemented in the versions plugin. Unfortunately it only seems to update the timestamp when you change the version. For snapshots that doesn't make sense (to me). That means that if I used this feature it would have to be supported by hand-written scripts, which I kind of dislike. Also, apparently, not all plugins know the convention about epoch timestamps (if you try it the build will fail). |
We could also hardcode the initial Maven build timestamp to the same one Gradle uses for its reproducible zip/jar tasks:
NOTE: In Gradle, this date is used when the archive task has the |
A hard-coded fictional date is kind of nonsense though, right? It's using a hard-to-guess arbitrary value to say "don't put any real timestamps in here please"? Is that necessary - maybe it is - maybe the JAR file standard (or something we absolutely cannot control) just has to have a timestamp, so this fictional one is the only workaround that preserves reproducible builds. Is that what is going on here? Setting a timestamp to an arbitrary value in the distant past seems like it will only confuse people (e.g. spring-projects/spring-framework#29633), but maybe it is less confusing than an arbitrary value in the near past. I still don't know. |
Yes, the table of contents of various archives formats (zip, jar, etc) require a timestamp. There are some complexities with date/times (see the javadoc on why Gradle picked that 1980 date). IMHO, the initial date is arbitrary, though aligning it with the last tag/release is probably ideal (keeps things consistent with future updates and can be used as an explanation as to why a date is picked) If folks are NOT using a maven plugin that automatically updates the |
Agree (but the adjective "initial" is misleading). However, this isn't supported by any of the plugins? We'd have to implement it with shell scripts or something. |
@dsyer I'm not sure what you mean by isn't supported by any of the plugins. To update the project version and date you could run something like: mvn versions:set -DgenerateBackupPoms=false -DnewVersion=<your-new-version-here>
# DgenerateBackupPoms is optional NOTE: @dsyer, I hope I'm not coming across as pushy. I just want to make sure I understand your concerns; maybe there is something we can do on the Maven side to make things better (even if there is no interest in merging this PR) |
IIRC that only works if the version changes. So there’s no way for snapshots to be up to date. Maybe that’s acceptable, but I’m not sure why it has to be if it is. No pushiness detected. I sense it is important, so it’s worth making sure I understand. Thank you for your patience. |
Set build output timestamp per: https://maven.apache.org/guides/mini/guide-reproducible-builds.html