JDK-6413452 : DefaultFileManager may throw "could not create parent directories" in concurrent execution
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris,windows_vista
  • CPU: generic
  • Submitted: 2006-04-14
  • Updated: 2012-03-23
  • Resolved: 2008-07-03
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.
JDK 7
7 b09Fixed
Related Reports
Relates :  
Relates :  
Description
We faced with "could not create parent directories" exception during the concurrent file compilation on the fast multi-cpu machine. If seems that the problem exists in the com.sun.tools.javac.util.DefaultFileManager. Let's consider the code below:
...
private void ensureParentDirectoriesExist() throws IOException {
            if (!hasParents) {
                File parent = f.getParentFile();
                if (parent != null && !parent.exists()) {
                //point #1
                    if (!parent.mkdirs()) {
		//point #2
                        throw new IOException("could not create parent directories");
                    }
                }
                hasParents = true;
            }	    
	}
...
Let's imagine the we are compiling two classes a.b.c.d.e.Cl and a.b.c.d.C2 in parallel and directory a/b/c/d/e has not been created yet. Processes 1 and 2 steps on point #1 simultaneously. The one of the processes creates the directory structure, for example 'a/b/c/d' and returns successfully. At the same moment other process invokes parent.mkdirs() and gets false becase some subdiretories has been already created by the process 1. As a result process 2 steps on point #2 and throws an exception.
I have reporoduced this problem using dmake. Please see /home/ag153348/tmp/compiler_bug/Makefile.

Command output for concurrent mode:
----------------------------------
ag153348@oink$ rm -rf classes; dmake all
dmake: defaulting to parallel mode.
See the man page dmake(1) for more information on setting up the .dmakerc file.
oink --> 1 job
/java/re/jdk/6/latest/binaries/solaris-sparc/bin/javac -d classes C1.java
oink --> 2 jobs
/java/re/jdk/6/latest/binaries/solaris-sparc/bin/javac -d classes C2.java
oink --> Job output
/java/re/jdk/6/latest/binaries/solaris-sparc/bin/javac -d classes C2.java
C2.java:2: error while writing a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.C2: could not create parent directories
class C2 {
^
1 error
*** Error code 1
dmake: Fatal error: Command failed for target `C2.ok'
Waiting for 1 job to finish
-------------------------------
Command output for single job mode:
----------------------------------
ag153348@oink$ rm -rf classes; dmake -j 1 all
dmake: defaulting to parallel mode.
See the man page dmake(1) for more information on setting up the .dmakerc file.
oink --> 1 job
/java/re/jdk/6/latest/binaries/solaris-sparc/bin/javac -d classes C1.java
oink --> 1 job
/java/re/jdk/6/latest/binaries/solaris-sparc/bin/javac -d classes C2.java
ag153348@oink$
----------------------------------------

Comments
EVALUATION There is potentially an underlying issue in File.mkdirs(), but that is pure Java code, with a suggested fix in 4742723. We should avoid using mkdirs until 4742723, meaning that we should create the parent directories explicitly, taking account of potential concurrency.
07-12-2006

EVALUATION Apparently, File.mkdirs() has problems as well. I have filed bug 6492293. I'm not exactly sure what to do about this bug.
10-11-2006

EVALUATION noreg-hard because the test involves concurrent access by separate compilers.
01-05-2006

EVALUATION See Suggested Fix
01-05-2006

SUGGESTED FIX if (parent != null && !parent.exists()) { if (!parent.mkdirs()) { + if (!parent.exists() || !parent.isDirectory()) throw new IOException("could not create parent directories"); } }
14-04-2006

WORK AROUND To workaround this problem for building the JCK we create the directory stucture in the build script.
14-04-2006