Saturday, February 12, 2005

A more useful way to write JAR files

The Java java.util.jar package has an ancient pedigree. Unfortunately, it shows that the early Java engineers did not all understand object-oriented design. Consider writing a file into a JAR:

// Write foo.jar!bar/qux.txt
JarOutputStream jos
        = new JarOutputStream(new File("foo.jar"));
jos.putNextEntry(new JarEntry("bar/qux.txt"));

Contrast with a more modern design:

NewerJarOutputStream newerJos
        = new NewerJarOutputStream(jarFile);
JarEntryOutputStream entryJos= newerJos.openEntry("bar/qux.txt");

The whole business with putNextEntry/closeEntry is lame, and managing a separate JarEntry object is annoying. What would NewerJarOutputStream and JarEntryOutputStream look like?

class NewerJarOutputStream extends JarOutputStream {
    public JarEntryOutputStream openEntry(final String name) {
        return new JarEntryOutputStream(this, name);

class JarEntryOutputStream extends OutputStream {
    private final NewerJarOutputStream jos;

    public JarEntryOutputStream(final NewerJarOutputStream jos,
            final String name) {
        this.jos = jos;

        jos.putNextEntry(new JarEntry(name));

    public void write(final int b) {

    public void close() {

What I have actually written is a SignedJarOutputStream to provide programmatic JAR signing and the attendent classes such as SignedJarFile, et al. Unfortunately, the literature is a bit dowdy, and Sun provides very little help. But the task was interesting, and the JAR signing specification is elegant and well-considered even if over-sparse. Factum est.

Post a Comment