Java print time of last compilation

There is no direct support for this in java, since there is no preprocessor. The closest equivalent is the "Build-Date" attribute in the JAR manifest. Many build systems add this attribute by default, or provide the means to add it.

You can then read the manifest of the JAR at runtime to get the date. The answer to this SO question describes how to read values from the JAR manifest.

The alternative is to use resource filtering to add the date into a properties file, which is then read at runtime. This is quite ad-hoc, non-standard and if you have many jars, with different compilation times, then this quickly becomes difficult to manage, unless you can factor this into a common part of how all the jars are built.


This question has been answered a long time ago. But in case someone swings by here's a solution that works for me, similar to what Supah Fly suggested but supports jar and file.

private long classBuildTimeMillis() throws URISyntaxException, IllegalStateException, IllegalArgumentException {
    URL resource = getClass().getResource(getClass().getSimpleName() + ".class");
    if (resource == null) {
        throw new IllegalStateException("Failed to find class file for class: " + 
                                        getClass().getName());
    }

    if (resource.getProtocol().equals("file")) {

        return new File(resource.toURI()).lastModified();

    } else if (resource.getProtocol().equals("jar")) {

        String path = resource.getPath();
        return new File(path.substring(5, path.indexOf("!"))).lastModified();

    } else {

        throw new IllegalArgumentException("Unhandled url protocol: " + 
                resource.getProtocol() + " for class: " +
                getClass().getName() + " resource: " + resource.toString());
    }
}

But this won't handle zip files or a static context, and it throws exceptions instead of returning null if things go south. This is a bit more friendly:

private static final Date buildDate = getClassBuildTime();

/**
 * Handles files, jar entries, and deployed jar entries in a zip file (EAR).
 * @return The date if it can be determined, or null if not.
 */
private static Date getClassBuildTime() {
    Date d = null;
    Class<?> currentClass = new Object() {}.getClass().getEnclosingClass();
    URL resource = currentClass.getResource(currentClass.getSimpleName() + ".class");
    if (resource != null) {
        if (resource.getProtocol().equals("file")) {
            try {
                d = new Date(new File(resource.toURI()).lastModified());
            } catch (URISyntaxException ignored) { }
        } else if (resource.getProtocol().equals("jar")) {
            String path = resource.getPath();
            d = new Date( new File(path.substring(5, path.indexOf("!"))).lastModified() );    
        } else if (resource.getProtocol().equals("zip")) {
            String path = resource.getPath();
            File jarFileOnDisk = new File(path.substring(0, path.indexOf("!")));
            //long jfodLastModifiedLong = jarFileOnDisk.lastModified ();
            //Date jfodLasModifiedDate = new Date(jfodLastModifiedLong);
            try(JarFile jf = new JarFile (jarFileOnDisk)) {
                ZipEntry ze = jf.getEntry (path.substring(path.indexOf("!") + 2));//Skip the ! and the /
                long zeTimeLong = ze.getTime ();
                Date zeTimeDate = new Date(zeTimeLong);
                d = zeTimeDate;
            } catch (IOException|RuntimeException ignored) { }
        }
    }
    return d;
}

Tags:

Java