JDK-4067481 : The jar utility sometimes fails exploding an archive. May be a bug in java.io.F
  • Type: Bug
  • Component: tools
  • Sub-Component: jar
  • Affected Version: 1.1.3,1.1.4,1.1.5,1.1.6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS:
    generic,solaris_2.5.1,windows_95,windows_nt generic,solaris_2.5.1,windows_95,windows_nt
  • CPU: generic,x86,sparc
  • Submitted: 1997-07-25
  • Updated: 1999-01-19
  • Resolved: 1999-01-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.2.0 1.2beta4Fixed
Related Reports
Duplicate :  
Relates :  
Description

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.


Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: generic FIXED IN: 1.2beta4 INTEGRATED IN: 1.2beta4 VERIFIED IN: 1.2fcs
14-06-2004

WORK AROUND Name: rlT66838 Date: 07/25/97 ======================================================================
11-06-2004

PUBLIC COMMENTS .
10-06-2004

EVALUATION Probably should fix this for 1.2. The File.getParent() problem has been fixed in 1.2beta4. Now the JAR extract works fine. ###@###.### 1998-06-22 Verified in 1.2fcsV build. ###@###.### 1998-12-10
22-06-1998