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

JAR file not closed after loading .properties file in ResourceBundle.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 1.3.0
    • core-libs
    • generic
    • generic



      Name: yyT116575 Date: 11/07/2000


      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
      Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

      I am seeing an issue where a JAR file remains open after ResourceBundle loads
      a resource file from it.

      The ResourceBundle class calls getResourceAsStream on the ClassLoader to
      open an InputStream to the resource. getResourceAsStream calls getResource
      to obtain a URL and then calls openStream on the URL. If the resource is from
      a JAR, then the underlying connection is a JarURLConnection. The
      JarURLConnection creates a ZipFile which returns a ZipFileInputStream
      (private class in ZipFile) as the InputStream. The ResourceBundle does close
      the InputStream after it is done with it but the underlying ZipFile is not
      closed and the file descriptor remains open.

      The impact of this is that if you try to delete or overwrite the JAR file you
      can't because it's still in use (NT complains - don't know about other
      platforms). We have implemented our own class loading mechanism that monitors
      a directory and loads/reloads/unloads classes and properties from JAR files.
      Once a JAR is loaded, I can't remove it from the directory because of the
      open handle. Worse yet, you may even run out of file handles if you load
      enough properties files.

      I think the problem lies with the JarURLConnection implementation. It should
      somehow close the ZipFile when the InputStream is closed.

      I implemented the following workaround in my custom class loader. I override
      the getResourceAsStream method and wrap the ZipFileInputStream in my own
      class which closes the ZipFile. This works for resources loaded by my class
      loaders but not for ones loaded by the system class loader.

      class JarFileClassLoader extends FileClassLoader
      {
          private static class ResourceInputStream extends InputStream
          {
              private InputStream is ;
              private ZipFile jarFile ;

              ResourceInputStream ( InputStream is, ZipFile jarFile )
              {
                  this.is = is ;
                  this.jarFile = jarFile ;
              }

              public int read ( byte b[], int off, int len ) throws IOException
              {
                  return is.read ( b, off, len ) ;
              }

              public int read () throws IOException
              {
                  return is.read () ;
              }

              public long skip ( long n ) throws IOException
              {
                  return is.skip ( n ) ;
              }

              public int available () throws IOException
              {
                  return is.available () ;
              }

              public void close () throws IOException
              {
                  is.close () ;
                  jarFile.close () ;
              }
          }
          
          .
          .
          .

          public InputStream getResourceAsStream ( String name )
          {
              InputStream stream = null ;
              ZipFile jarFile = null ;
              try
              {
                  jarFile = new ZipFile ( file ) ;
                  ZipEntry jarEntry = (ZipEntry) jarFile.getEntry ( name ) ;
                  if ( jarEntry != null )
                  {
                      InputStream is = jarFile.getInputStream ( jarEntry ) ;
                      stream = new ResourceInputStream ( is, jarFile ) ;
                  }
              }
              catch ( Throwable e )
              {
              }

              if ( jarFile != null && stream == null )
              {
                  try
                  {
                      jarFile.close () ;
                  }
                  catch ( Exception e ) {}
              }

              return stream ;
          }
      }
      (Review ID: 111910)
      ======================================================================

            kkladkosunw Konstantin Kladko (Inactive)
            yyoungsunw Yung-ching Young (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: