### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ClassFile.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java,v retrieving revision 1.144 diff -u -r1.144 ClassFile.java --- compiler/org/eclipse/jdt/internal/compiler/ClassFile.java 5 Dec 2006 22:02:24 -0000 1.144 +++ compiler/org/eclipse/jdt/internal/compiler/ClassFile.java 6 Dec 2006 18:26:31 -0000 @@ -121,6 +121,8 @@ public static final int INITIAL_HEADER_SIZE = 1500; public static final int INNER_CLASSES_SIZE = 5; + private static int MAX_TIME = -1; + private static final int MAX_COUNT = 50; /** * INTERNAL USE-ONLY * Build all the directories and subdirectories corresponding to the packages names @@ -142,14 +144,16 @@ char fileSeparatorChar = File.separatorChar; String fileSeparator = File.separator; File f; - outputPath = outputPath.replace('/', fileSeparatorChar); - // these could be optimized out if we normalized paths once and for - // all - relativeFileName = relativeFileName.replace('/', fileSeparatorChar); + if (fileSeparatorChar != '/') { + // these could be optimized out if we normalized paths once and for all + outputPath = outputPath.replace('/', fileSeparatorChar); + relativeFileName = relativeFileName.replace('/', fileSeparatorChar); + } String outputDirPath, fileName; int separatorIndex = relativeFileName.lastIndexOf(fileSeparatorChar); + boolean pathEndsWithSep = outputPath.endsWith(fileSeparator); if (separatorIndex == -1) { - if (outputPath.endsWith(fileSeparator)) { + if (pathEndsWithSep) { outputDirPath = outputPath.substring(0, outputPath.length() - 1); fileName = outputPath + relativeFileName; } else { @@ -157,13 +161,11 @@ fileName = outputPath + fileSeparator + relativeFileName; } } else { - if (outputPath.endsWith(fileSeparator)) { - outputDirPath = outputPath + - relativeFileName.substring(0, separatorIndex); + if (pathEndsWithSep) { + outputDirPath = outputPath + relativeFileName.substring(0, separatorIndex); fileName = outputPath + relativeFileName; } else { - outputDirPath = outputPath + fileSeparator + - relativeFileName.substring(0, separatorIndex); + outputDirPath = outputPath + fileSeparator + relativeFileName.substring(0, separatorIndex); fileName = outputPath + fileSeparator + relativeFileName; } } @@ -171,73 +173,109 @@ f.mkdirs(); if (f.isDirectory()) { return fileName; + } + + // the directory creation failed for some reason - retry using + // a slower algorithm so as to refine the diagnostic + // First create the output dir + if (pathEndsWithSep) { + outputPath = outputPath.substring(0, outputPath.length() - 1); + } + f = new File(outputPath); + boolean checkFileType = false; + if (f.exists()) { + checkFileType = true; // pre-existed } else { - // the directory creation failed for some reason - retry using - // a slower algorithm so as to refine the diagnostic - if (outputPath.endsWith(fileSeparator)) { - outputPath = outputPath.substring(0, outputPath.length() - 1); + // we have to create that directory + int count = 0; + while (!f.mkdirs() && count < MAX_COUNT) { + if (f.exists()) { + // someone else created f -- need to check its type + checkFileType = true; + break; + } + try { + Thread.sleep(10); + count++; + } catch (InterruptedException e) { + break; + } } - f = new File(outputPath); - boolean checkFileType = false; + if (!f.exists()) { + System.out.println("ClassFile: output directory "+f+" does not exist after creation!"); + // no one could create f -- complain + throw new IOException(Messages.bind( + Messages.output_notValidAll, f.getAbsolutePath())); + } + if (count > 0) { + int time = count * 10; + if (time > MAX_TIME) MAX_TIME = time; + System.out.println("ClassFile: takes "+time+"ms (max="+MAX_TIME+"ms) before the output directory "+f+" was created..."); + } + } + if (checkFileType) { + if (!f.isDirectory()) { + System.out.println("ClassFile: output "+f+" is not a directory!"); + throw new IOException(Messages.bind( + Messages.output_isFile, f.getAbsolutePath())); + } + } + + // Then create sub-directories + StringBuffer outDir = new StringBuffer(outputPath); + outDir.append(fileSeparator); + StringTokenizer tokenizer = new StringTokenizer(relativeFileName, fileSeparator); + String token = tokenizer.nextToken(); + while (tokenizer.hasMoreTokens()) { + f = new File(outDir.append(token).append(fileSeparator).toString()); + checkFileType = false; // reset if (f.exists()) { - checkFileType = true; // pre-existed + checkFileType = true; // this is suboptimal, but it catches corner cases + // in which a regular file pre-exists } else { // we have to create that directory - if (!f.mkdirs()) { - if (f.exists()) { - // someone else created f -- need to check its type - checkFileType = true; - } else { - // no one could create f -- complain - throw new IOException(Messages.bind( - Messages.output_notValidAll, f.getAbsolutePath())); - } - } - } - if (checkFileType) { - if (!f.isDirectory()) { - throw new IOException(Messages.bind( - Messages.output_isFile, f.getAbsolutePath())); + int count = 0; + while (!f.mkdir() && count < MAX_COUNT) { + if (f.exists()) { + // someone else created f -- need to check its type + checkFileType = true; + break; + } + try { + // need to try again some times as some OS can take some times + // before the directory really exists... + Thread.sleep(10); + count++; + } catch (InterruptedException e) { + break; + } + } + if (!f.exists()) { + System.out.println("ClassFile: output sub-directory "+f+" does not exist after creation!"); + // no one could create f -- complain + throw new IOException(Messages.bind( + Messages.output_notValid, + outDir.substring(outputPath.length() + 1, + outDir.length() - 1), + outputPath)); } + if (count > 0) { + int time = count * 10; + if (time > MAX_TIME) MAX_TIME = time; + System.out.println("ClassFile: takes "+time+"ms (max="+MAX_TIME+"ms) before the output sub-directory "+f+" was created..."); + } } - StringBuffer outDir = new StringBuffer(outputPath); - outDir.append(fileSeparator); - StringTokenizer tokenizer = - new StringTokenizer(relativeFileName, fileSeparator); - String token = tokenizer.nextToken(); - while (tokenizer.hasMoreTokens()) { - f = new File(outDir.append(token).append(fileSeparator).toString()); - checkFileType = false; // reset - if (f.exists()) { - checkFileType = true; // this is suboptimal, but it catches corner cases - // in which a regular file pre-exists - } else { - // we have to create that directory - if (!f.mkdir()) { - if (f.exists()) { - // someone else created f -- need to check its type - checkFileType = true; - } else { - // no one could create f -- complain - throw new IOException(Messages.bind( - Messages.output_notValid, - outDir.substring(outputPath.length() + 1, - outDir.length() - 1), - outputPath)); - } - } - } - if (checkFileType) { - if (!f.isDirectory()) { - throw new IOException(Messages.bind( - Messages.output_isFile, f.getAbsolutePath())); - } - } - token = tokenizer.nextToken(); - } - // token contains the last one - return outDir.append(token).toString(); + if (checkFileType) { + if (!f.isDirectory()) { + System.out.println("ClassFile: sub output "+f+" is not a directory!"); + throw new IOException(Messages.bind( + Messages.output_isFile, f.getAbsolutePath())); + } + } + token = tokenizer.nextToken(); } + // token contains the last one + return outDir.append(token).toString(); } /** * INTERNAL USE-ONLY @@ -343,11 +381,13 @@ String relativeFileName, ClassFile classFile) throws IOException { - BufferedOutputStream output = null; +// BufferedOutputStream output = null; + File file = null; if (generatePackagesStructure) { - output = new BufferedOutputStream( - new FileOutputStream( - new File(buildAllDirectoriesInto(outputPath, relativeFileName)))); +// output = new BufferedOutputStream( +// new FileOutputStream( +// new File(buildAllDirectoriesInto(outputPath, relativeFileName)))); + file = new File(buildAllDirectoriesInto(outputPath, relativeFileName)); } else { String fileName = null; char fileSeparatorChar = File.separatorChar; @@ -370,16 +410,40 @@ fileName = outputPath + fileSeparator + relativeFileName.substring(indexOfPackageSeparator + 1, length); } } - output = new BufferedOutputStream( - new FileOutputStream( - new File(fileName))); +// output = new BufferedOutputStream( +// new FileOutputStream( +// new File(fileName))); + file = new File(fileName); } + + // Create file + BufferedOutputStream output = new BufferedOutputStream( + new FileOutputStream(file)); + + // Wait for file creation + int count = 0, max = 50; + while (!file.exists() && count < max) { + try { + Thread.sleep(10); + count++; + } catch (InterruptedException e) { + break; + } + } + if (count > 0) { + int time = count * 10; + if (time > MAX_TIME) MAX_TIME = time; + System.out.println("ClassFile: takes "+time+"ms (max="+MAX_TIME+"ms) before the file "+file+" was created..."); + } + + // Write contents try { // if no IOException occured, output cannot be null output.write(classFile.header, 0, classFile.headerOffset); output.write(classFile.contents, 0, classFile.contentsOffset); output.flush(); } catch(IOException e) { + System.out.println("ClassFile: exception ["+e.getMessage()+"] while writing class file "+file); throw e; } finally { output.close(); #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/Requestor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Requestor.java,v retrieving revision 1.16 diff -u -r1.16 Requestor.java --- src/org/eclipse/jdt/core/tests/compiler/regression/Requestor.java 29 Mar 2006 03:50:23 -0000 1.16 +++ src/org/eclipse/jdt/core/tests/compiler/regression/Requestor.java 6 Dec 2006 18:26:32 -0000 @@ -105,6 +105,8 @@ try { ClassFile.writeToDisk(true, outputPath, relativeName, classFile); } catch(IOException e) { + System.out.println("Still got an exception ["+e.getMessage()+"] while writing class file:"+new String(classFile.fileName())); + e.printStackTrace(); } } } Index: src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java,v retrieving revision 1.70 diff -u -r1.70 AbstractRegressionTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java 20 Nov 2006 14:17:13 -0000 1.70 +++ src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java 6 Dec 2006 18:26:32 -0000 @@ -1313,7 +1313,7 @@ // clean up output dir File outputDir = new File(OUTPUT_DIR); if (outputDir.exists()) { - Util.rmdir(outputDir); + Util.flushDirectoryContent(outputDir); } super.tearDown(); if (RUN_JAVAC) { Index: src/org/eclipse/jdt/core/tests/util/Util.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java,v retrieving revision 1.52 diff -u -r1.52 Util.java --- src/org/eclipse/jdt/core/tests/util/Util.java 11 Oct 2006 09:15:32 -0000 1.52 +++ src/org/eclipse/jdt/core/tests/util/Util.java 6 Dec 2006 18:26:32 -0000 @@ -175,6 +175,8 @@ File file = new File(classpaths[i]); if (!file.exists()) { file.mkdirs(); + if (!file.exists()) + waitUntilReady(file, true/* should exist */); } } return defaultClassPaths; @@ -183,8 +185,11 @@ String[] classLibs = getJavaClassLibs(); final int length = classLibs.length; File dir = new File(classpath); - if (!dir.exists()) + if (!dir.exists()) { dir.mkdirs(); + if (!dir.exists()) + waitUntilReady(dir, true/* should exist */); + } String[] defaultClassPaths = new String[length + 1]; if (inFront) { System.arraycopy(classLibs, 0, defaultClassPaths, 1, length); @@ -551,7 +556,8 @@ flushDirectoryContent(current); } if (!current.delete()) - System.err.println("Could not delete " + current.getName()); +// System.err.println("Could not delete " + current.getName()); + waitUntilReady(current, false /* should not exist */); } } } @@ -752,7 +758,9 @@ public static void zip(File rootDir, String zipPath) throws IOException { ZipOutputStream zip = null; try { - zip = new ZipOutputStream(new FileOutputStream(zipPath)); + File zipFile = new File(zipPath); + zip = new ZipOutputStream(new FileOutputStream(zipFile)); + waitUntilReady(zipFile, true /* shouldExist */); zip(rootDir, zip, rootDir.getPath().length()+1); // 1 for last slash } finally { if (zip != null) { @@ -779,4 +787,46 @@ } } } +private static int MAX_TIME = 0; +private static void waitUntilReady(File dir, boolean shouldExist) { + int count = 0; + while (dir.exists() != shouldExist && count < 50) { + if (count == 0) { + if (shouldExist) { + System.out.println(dir+" was not created after mkdirs()!"); + } else { + System.out.println(dir+" was not removed after delete()!"); + } + System.out.print(" - retry (500ms max): "); + } + try { + count++; + Thread.sleep(10); + System.out.print('.'); + if (shouldExist) { + dir.mkdirs(); + } else { + dir.delete(); + } + } + catch (InterruptedException ie) { + break; // end loop + } + } + if (count != 0) { + if (dir.exists() != shouldExist) { + System.out.println(": Still not there => throws exception!"); + if (shouldExist) { + throw new RuntimeException(dir+" should exist after its creation!!!"); + } else { + throw new RuntimeException(dir+" should not exist after its deletion!!!"); + } + } + String str = shouldExist ? "exists" : "was removed"; + int time = count * 10; + if (time > MAX_TIME) MAX_TIME = time; + System.out.println(" ("+time+"ms [max="+MAX_TIME+"ms] before the directory "+str+"!)"); + } + +} }