United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6413452 DefaultFileManager may throw "could not create parent directories" in concurrent execution
6413452 : DefaultFileManager may throw "could not create parent directories" in concurrent execution

Details
Type:
Bug
Submit Date:
2006-04-14
Status:
Closed
Updated Date:
2012-03-23
Project Name:
JDK
Resolved Date:
2008-07-03
Component:
tools
OS:
solaris,windows_vista
Sub-Component:
javac
CPU:
generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:
7

Related Reports
Relates:
Relates:

Sub Tasks

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.
                                     
2006-12-07
EVALUATION

Apparently, File.mkdirs() has problems as well.  I have filed
bug 6492293.

I'm not exactly sure what to do about this bug.
                                     
2006-11-10
EVALUATION

See Suggested Fix
                                     
2006-05-01
EVALUATION

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

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

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



Hardware and Software, Engineered to Work Together