guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Reproducible jar archives.


From: Ricardo Wurmus
Subject: Reproducible jar archives.
Date: Wed, 30 Dec 2015 20:03:59 +0100
User-agent: mu4e 0.9.13; emacs 24.5.1

Hi Guix,

Java libraries are usually installed as jar archives.  These are
(optionally compressed) archives containing the “.class” files;
optionally, they may also contain a manifest.

These archives are created by the “jar” tool, which is part of the JDK;
they can also be created by “fastjar”, an alternative implementation in
C.

Unlike “tar” the “jar” tool does not support anything like the “--mtime”
flag, so file modification dates cannot be reset before packing.  Also,
the manifest is usually generated automatically (unless manually
provided) and the generated directories and the manifest file itself
have uncontrollable timestamps.

Although compiling “.java” to “.class” with the javac compiler is
deterministic, packaging up the “.class” files to a “.jar” is not for
the above reasons.

For Java projects without a build system this is not so bad: we can
generate our own build.xml and build the project with Ant.  The
build.xml would just have to run a command to reset the modification
time of all files before archiving them.  (This is what my WIP
‘ant-build-system’ does and packages built with it are, in fact,
deterministic.)

For many non-trivial projects, however, we have no way to easily inject
a phase before “jar” is called, because of some indirection through
build plugins (in the case of Maven projects) or because of a convoluted
build.xml for Ant, which may use different Ant tasks to package the
“.jar”.  I only came up with two ways to get around this problem:

* build the “.jar” archive as usual, then unpack it, reset all file
  timestamps, and archive them again (this time without generating an
  additional manifest)

* patch up the “jar” tool so that it resets the mtime for archive
  contents.

The first approach might work if we can reliably find a point in the
build process where all “jar” archives have been created (after the
“build” phase?).  It’s an ugly solution because we have to do so much
more work for every “jar” (unpacking, touching, and repacking can take a
lot of time and space for big projects).

The second approach is tempting.  I looked at the “fastjar” code and
making it set the file modification time is trivial; of course this must
be optional (e.g. when a certain environment variable is set) lest this
affects operation under normal conditions.  But it’s also really hacky.

I haven’t looked at the sources for the JDK-provided “jar” tool yet, so
I cannot say if that would work.

What do you think about this?  Other ideas maybe?

~~ Ricardo




reply via email to

[Prev in Thread] Current Thread [Next in Thread]