OpenJDK / jdk / jdk10
changeset 21664:81740736e62f
8022213: Intermittent test failures in java/net/URLClassLoader
Reviewed-by: dxu, alanb
author | chegar |
---|---|
date | Wed, 13 Nov 2013 16:44:12 +0000 |
parents | f364900c7cc5 |
children | 18a9cae3b4d5 |
files | jdk/test/java/net/URLClassLoader/closetest/CloseTest.java jdk/test/java/net/URLClassLoader/closetest/Common.java jdk/test/java/net/URLClassLoader/closetest/GetResourceAsStream.java jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java |
diffstat | 4 files changed, 180 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/test/java/net/URLClassLoader/closetest/CloseTest.java Wed Nov 13 07:49:42 2013 -0800 +++ b/jdk/test/java/net/URLClassLoader/closetest/CloseTest.java Wed Nov 13 16:44:12 2013 +0000 @@ -25,7 +25,8 @@ * @test * @bug 4167874 * @library ../../../../com/sun/net/httpserver - * @build FileServerHandler + * @library /lib/testlibrary + * @build FileServerHandler jdk.testlibrary.FileUtils * @run shell build.sh * @run main/othervm CloseTest * @summary URL-downloaded jar files can consume all available file descriptors
--- a/jdk/test/java/net/URLClassLoader/closetest/Common.java Wed Nov 13 07:49:42 2013 -0800 +++ b/jdk/test/java/net/URLClassLoader/closetest/Common.java Wed Nov 13 16:44:12 2013 +0000 @@ -23,6 +23,9 @@ import java.io.*; import java.net.*; +import java.nio.file.Files; +import jdk.testlibrary.FileUtils; +import static java.nio.file.StandardCopyOption.*; public class Common { @@ -39,42 +42,16 @@ if (!src.isFile()) { throw new RuntimeException ("File not found: " + src.toString()); } - dst.delete(); - dst.createNewFile(); - FileInputStream i = new FileInputStream (src); - FileOutputStream o = new FileOutputStream (dst); - byte[] buf = new byte [1024]; - int count; - while ((count=i.read(buf)) >= 0) { - o.write (buf, 0, count); - } - i.close(); - o.close(); + Files.copy(src.toPath(), dst.toPath(), REPLACE_EXISTING); } catch (IOException e) { throw new RuntimeException (e); } } - static void rm_minus_rf (File path) { - if (!path.exists()) { + static void rm_minus_rf (File path) throws IOException, InterruptedException { + if (!path.exists()) return; - } - if (path.isFile()) { - if (!path.delete()) { - throw new RuntimeException ("Could not delete " + path); - } - } else if (path.isDirectory ()) { - String[] names = path.list(); - File[] files = path.listFiles(); - for (int i=0; i<files.length; i++) { - rm_minus_rf (new File(path, names[i])); - } - if (!path.delete()) { - throw new RuntimeException ("Could not delete " + path); - } - } else { - throw new RuntimeException ("Trying to delete something that isn't a file or a directory"); - } + FileUtils.deleteFileTreeWithRetry(path.toPath()); } static void copyDir (File src, File dst) {
--- a/jdk/test/java/net/URLClassLoader/closetest/GetResourceAsStream.java Wed Nov 13 07:49:42 2013 -0800 +++ b/jdk/test/java/net/URLClassLoader/closetest/GetResourceAsStream.java Wed Nov 13 16:44:12 2013 +0000 @@ -24,6 +24,8 @@ /** * @test * @bug 6899919 + * @library /lib/testlibrary + * @build jdk.testlibrary.FileUtils * @run shell build2.sh * @run main/othervm GetResourceAsStream */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/FileUtils.java Wed Nov 13 16:44:12 2013 +0000 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.testlibrary; + +import java.io.IOException; +import java.nio.file.DirectoryNotEmptyException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; + + +/** + * Common library for various test file utility functions. + */ +public final class FileUtils { + + private static final boolean isWindows = + System.getProperty("os.name").startsWith("Windows"); + private static final int RETRY_DELETE_MILLIS = isWindows ? 500 : 0; + private static final int MAX_RETRY_DELETE_TIMES = isWindows ? 15 : 0; + + /** + * Deletes a file, retrying if necessary. + * + * @param path the file to delete + * + * @throws NoSuchFileException + * if the file does not exist (optional specific exception) + * @throws DirectoryNotEmptyException + * if the file is a directory and could not otherwise be deleted + * because the directory is not empty (optional specific exception) + * @throws IOException + * if an I/O error occurs + */ + public static void deleteFileWithRetry(Path path) + throws IOException + { + try { + deleteFileWithRetry0(path); + } catch (InterruptedException x) { + throw new IOException("Interrupted while deleting.", x); + } + } + + private static void deleteFileWithRetry0(Path path) + throws IOException, InterruptedException + { + int times = 0; + IOException ioe = null; + while (true) { + try { + Files.delete(path); + while (Files.exists(path)) { + times++; + if (times > MAX_RETRY_DELETE_TIMES) + throw new IOException("File still exists after " + times + " waits."); + Thread.sleep(RETRY_DELETE_MILLIS); + } + break; + } catch (NoSuchFileException | DirectoryNotEmptyException x) { + throw x; + } catch (IOException x) { + // Backoff/retry in case another process is accessing the file + times++; + if (ioe == null) + ioe = x; + else + ioe.addSuppressed(x); + + if (times > MAX_RETRY_DELETE_TIMES) + throw ioe; + Thread.sleep(RETRY_DELETE_MILLIS); + } + } + } + + /** + * Deletes a directory and its subdirectories, retrying if necessary. + * + * @param dir the directory to delete + * + * @throws IOException + * If an I/O error occurs. Any such exceptions are caught + * internally. If only one is caught, then it is re-thrown. + * If more than one exception is caught, then the second and + * following exceptions are added as suppressed exceptions of the + * first one caught, which is then re-thrown. + */ + public static void deleteFileTreeWithRetry(Path dir) + throws IOException + { + IOException ioe = null; + final List<IOException> excs = deleteFileTreeUnchecked(dir); + if (!excs.isEmpty()) { + ioe = excs.remove(0); + for (IOException x : excs) + ioe.addSuppressed(x); + } + if (ioe != null) + throw ioe; + } + + public static List<IOException> deleteFileTreeUnchecked(Path dir) { + final List<IOException> excs = new ArrayList<>(); + try { + java.nio.file.Files.walkFileTree(dir, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + try { + deleteFileWithRetry0(file); + } catch (IOException x) { + excs.add(x); + } catch (InterruptedException x) { + excs.add(new IOException("Interrupted while deleting.", x)); + return FileVisitResult.TERMINATE; + } + return FileVisitResult.CONTINUE; + } + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { + try { + deleteFileWithRetry0(dir); + } catch (IOException x) { + excs.add(x); + } catch (InterruptedException x) { + excs.add(new IOException("Interrupted while deleting.", x)); + return FileVisitResult.TERMINATE; + } + return FileVisitResult.CONTINUE; + } + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + excs.add(exc); + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException x) { + excs.add(x); + } + return excs; + } +} +