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

The jar utility sometimes fails exploding an archive. May be a bug in java.io.F

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.2.0
    • 1.1.3, 1.1.4, 1.1.5, 1.1.6
    • tools
    • None
    • jar
    • 1.2beta4
    • generic, x86, sparc
    • generic, solaris_2.5.1, windows_95, windows_nt
    • Verified



      Name: rlT66838 Date: 07/25/97


      The jar utility sometimes fails exploding an archive. The failing case is
      when a directory is named in the archive, and the parent directory of that
      directory doesn't already exist. This turns out arguably to be a bug in the
      java.io.File.getParent() method.

      Consider the following sample program:

      package aaa.bbb;

      class Demo {
         public static void main(String[] args) {
            System.out.println("Hello");
         }
      }

      Compile that program with the command: javac -d . Demo.java
      Create an archive with the command: jar cf demo.jar aaa/bbb
      To reproduce the problem, erase the aaa directory and all files and directories
      underneath it, and issue the command: jar xf demo.jar

      The given error messages are:
      java.io.IOException: aaa/bbb/: could not create directory
              at sun.tools.jar.Main.extractFile(Main.java:395)
              at sun.tools.jar.Main.extract(Main.java:375)
              at sun.tools.jar.Main.run(Main.java:106)
              at sun.tools.jar.Main.main(Main.java:524)

      The form of the jar command used to create the archive causes an entry for the
      directory "aaa/bbb/" to be placed in the archive (notice the trailing path
      separator), but not an entry for "aaa/". When exploding the archive, the jar
      utility creates a java.io.File object out of the string "aaa/bbb/". It then
      calls File.mkdirs() to create the directory and any necessary parent
      directories. The File.mkdirs() method tries creating (via a call to mkdir())
      "aaa/bbb/" immediately. When that fails, it calls File.getParent(), which
      returns "aaa/bbb". This is the crux of the problem. This path is the same as
      the original path, except for the trailing path separator. It is NOT the
      parent directory of the original path. Consequently, after finally creating
      "aaa/bbb", File.mkdirs() tries to create "aaa/bbb/". This fails, because now
      the directory exists, causing the entire File.mkdirs() call to return false
      (even though the directory was, in fact, created).

      It seems to me there are several ways to fix this: You could either have the
      jar command trim off the trailing path separator before calling File.mkdirs(),
      or change the File class to realize that some trailing path separators are
      irrelevant (at least File.getParent() would need to be changed in this way).
      As an aside, File.getParent() also fails to consider that on UNIX systems, in
      general, multiple slashes between directory names should be treated as a
      single slash. This is mandated by this POSIX.1 standard.

      Creating the original archive with: jar cf demo.jar aaa
      would have avoided the problem, because the aaa directory will now have its
      own entry in the archive, so that by the time aaa/bbb is processed, aaa will
      already exist. This avoids the File.mkdirs() limitation. But I would argue
      that an archive shouldn't necessarily need to contain entries for every parent
      of every directory named within. Or if it should, that the jar utility ought
      to create them itself.

      This problem is important to my programming organization because we have a
      utility that merges two jar files that operates by exploding them both. The
      explode operations are failing, which causes the merge operation to fail,
      which causes the whole build operation to fail.

      company - IBM , email - ###@###.###
      ======================================================================


      Create a jar with files down a subdirectory tree:

        JAR -cf test.jar COM\lotus

      when you unJAR them:

        JAR -xf test.jar

      in a directory in which COM\lotus does not exist,
      you get:

      D:\TEMP2>e:\jdk1.1.4\bin\jar -xf test.jar
      java.io.IOException: COM\lotus\: could not create directory
              at sun.tools.jar.Main.extractFile(Main.java:395)
              at sun.tools.jar.Main.extract(Main.java:375)
              at sun.tools.jar.Main.run(Main.java:106)
              at sun.tools.jar.Main.main(Main.java:524)

      even though the directories are, in fact, created.
      The problem appears to be that JAR tries to make
      COM\lotus instead of COM, then COM\lotus. You
      can see this with:

        JAR -tf test.jar

      The first directory listed before the files in the
      JAR will be

        COM\lotus

      If you created the JAR with

        JAR -cf test.jar COM

      then you will see

        COM
        COM\lotus

      in a list of the JAR contents. I tested this
      again with 1.1.5 and get the same failure as I did
      on 1.1.4.

            dconnellsunw David Connelly (Inactive)
            rlewis Roger Lewis (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: