alexantd alexantd - 4 months ago 21
Java Question

Class.getResource() returns null after a long time running

I'm using

Class.getResource()
to load a file from the jar of a long-running Java app. It works fine. But after the app has been running for a long time, it starts returning
null
.

How do I troubleshoot this? All I can see are exceptions caused by
getResource()
returning
null
; but I can't find out why it's returning
null
.

I have checked for unclosed streams returned by
Class.getResourceAsStream()
, but I'm not calling that. (Although, one of my libraries might...) I have also checked for FileInputStreams that aren't being closed, but I haven't found any. (FileInputStreams continue to be usable while this is happening.)

Edit: this appears to be the same issue as this one. Also, possibly related.

Answer

I fixed it. I had code that was reading the version out of MANIFEST.MF from an InputStream returned by URL.openStream():

String manifestPath = classPath.substring(0, webInfIndex) +
        "/META-INF/MANIFEST.MF";

// DON'T DO THIS!!!
// openStream() returns an InputStream that never gets closed.
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
Attributes attr = manifest.getMainAttributes();
String version = attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);

Fixing the leak using Java 7 try-with-resources:

try (InputStream inputStream = new URL(manifestPath).openStream()) {
    Manifest manifest = new Manifest(inputStream);
    Attributes attr = manifest.getMainAttributes();
    String version = attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
}