Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8132359

Amend JarURLConnection::getJarFile() to return JarFile object reference for nonexistent JAR file entry URL

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • tbd
    • 8-pool, 9
    • core-libs
    • x86_64
    • windows_7

      FULL PRODUCT VERSION :
      6u45
      7u79, 7u70
      8u45, 8u51

      ADDITIONAL OS VERSION INFORMATION :
      Windows 7 64-bit
      Windows 7 32-bit
      CentOS 6.6 64-bit
      RHEL 5.9 32-bit

      A DESCRIPTION OF THE PROBLEM :
      There is a resource leak in JarURLConnection.getJarFile() when a file is not found.
      A FileNotFOundException is thrown and the underlining opened JarFile underneath is not closed.

      This test program shows resource leak in java.net.JarURLConnection's getJarFile() when given an non-existent file to lookup in the jar file.

      Under Windows, the last printout shows that it is not able to remove the test input jar file. Any input jar file can be used to test this as long as it does not contain "/testNonExistentFile.xyz" in the jar file.

      WARN: test program will try to delete the input file, so use with a "temporary" copy of an existing jar file.

      === test.java ===

      import java.io.File;
      import java.net.JarURLConnection;
      import java.net.URL;
      import java.net.URLConnection;
      import java.util.jar.JarFile;

      public class test {

        public static void getJarFile(String urlstr) throws Exception {
          System.out.println("testing URL: " + urlstr);
          URL url = new URL(urlstr);
          URLConnection urlConnection = url.openConnection();
          if (urlConnection instanceof JarURLConnection) {
            JarURLConnection jarUrlConnection = (JarURLConnection) urlConnection;
            JarFile jarFile = jarUrlConnection.getJarFile();
            System.out.println(" Got JarFile : " + jarFile);
            System.out.println(" JarFile.name : " + ((jarFile != null) ? jarFile.getName() : ""));
            jarFile.close();
            System.out.println(" Closed JarFile " + jarFile);

          } else if (urlConnection != null) {
            System.err.println(" URLConnection.class: " + urlConnection.getClass());
          }
        }

        public static void main(String[] args) {
          if (args.length < 1) {
            error("Usage: <file.jar>");
          }
          String jarFilename = args[0];
          File file = new File(jarFilename);
          if (!file.exists()) {
            error("input jar file does not exists: " + file);
          }

          String nonExistentFileInJar = "jar:file:" + jarFilename + "!/testNonExistentFile.xyz";
          try {
            getJarFile(nonExistentFileInJar);
          } catch (Exception e) {
            e.printStackTrace();
          }

          boolean result = file.delete();
          System.out.println("Able to remove test jar file? " + result);

          if (!result) {
            error("Unable to remove test jar file: " + jarFilename);
          }
        }

        static void error(String msg) {
          System.err.println(msg);
          System.exit(1);
        }
      }


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      run test program under Windows with path to an existing jar file (make copy of any jar file as test program will try to delete it). Under Windows when a file is still open (i.e. the resource leak),

      create junk.jar
      jar cvf junk.jar test.java
      java -cp . test junk.jar


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      C:\Users\ntn>\java\java7\bin\java -cp . test junk.jar
      testing URL: jar:file:junk.jar!/testNonExistentFile.xyz
      java.io.FileNotFoundException: JAR entry testNonExistentFile.xyz not found in junk.jar
              at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:140)
              at sun.net.www.protocol.jar.JarURLConnection.getJarFile(JarURLConnection.java:89)
              at test.getJarFile(test.java:15)
              at test.main(test.java:38)
      Able to remove test jar file? true

      ACTUAL -
      C:\Users\ntn>\java\java7\bin\java -cp . test junk.jar
      testing URL: jar:file:junk.jar!/testNonExistentFile.xyz
      java.io.FileNotFoundException: JAR entry testNonExistentFile.xyz not found in junk.jar
              at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:140)
              at sun.net.www.protocol.jar.JarURLConnection.getJarFile(JarURLConnection.java:89)
              at test.getJarFile(test.java:15)
              at test.main(test.java:38)
      Able to remove test jar file? false
      Unable to remove test jar file: junk.jar


      REPRODUCIBILITY :
      This bug can be reproduced always.

            michaelm Michael McMahon
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: