提交 953dcdab 编写于 作者: W weijun

6894534: SeedGenerator shouldn't require java.nio.file to be present

Reviewed-by: alanb
上级 6b1b12bc
......@@ -63,13 +63,13 @@ package sun.security.provider;
* @author Gadi Guy
*/
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.security.*;
import java.io.*;
import java.util.Properties;
import java.util.Enumeration;
import java.net.*;
import java.nio.file.DirectoryStream;
import java.nio.file.Path;
import java.util.Random;
import sun.security.util.Debug;
......@@ -183,26 +183,38 @@ abstract class SeedGenerator {
// The temporary dir
File f = new File(p.getProperty("java.io.tmpdir"));
int count = 0;
DirectoryStream<Path> ds
= f.toPath().newDirectoryStream();
try {
// Go thru files in the tmp dir using NIO's
// DirectoryStream. Fallback to File.list()
// if NIO is not available.
if (NIODirectoryStream.isAvailable()) {
int count = 0;
Iterable<?> stream =
NIODirectoryStream.newDirectoryStream(f);
// We use a Random object to choose what file names
// should be used. Otherwise on a machine with too
// many files, the same first 1024 files always get
// used. Any, We make sure the first 512 files are
// always used.
Random r = new Random();
for (Path path: ds) {
if (count < 512 || r.nextBoolean()) {
md.update(path.getName().toString().getBytes());
}
if (count++ > 1024) {
break;
try {
for (Object entry: stream) {
if (count < 512 || r.nextBoolean()) {
md.update(NIODirectoryStream.getName(
entry).getBytes());
}
if (count++ > 1024) {
break;
}
}
} finally {
((Closeable)stream).close();
}
} else {
String[] sa = f.list();
for(int i = 0; i < sa.length; i++) {
md.update(sa[i].getBytes());
}
} finally {
ds.close();
}
} catch (Exception ex) {
md.update((byte)ex.hashCode());
......@@ -505,4 +517,76 @@ abstract class SeedGenerator {
}
/**
* A wrapper of NIO DirectoryStream using reflection.
*/
private static class NIODirectoryStream {
private static final Class<?> pathClass =
getClass("java.nio.file.Path");
private static final Method toPathMethod =
(pathClass == null) ? null : getMethod(File.class, "toPath");
private static final Method getNameMethod =
getMethod(pathClass, "getName");
private static final Method newDirectoryStreamMethod =
getMethod(pathClass, "newDirectoryStream");
private static Class<?> getClass(String name) {
try {
return Class.forName(name, true, null);
} catch (ClassNotFoundException e) {
return null;
}
}
private static Method getMethod(Class<?> clazz,
String name,
Class<?>... paramTypes) {
if (clazz != null) {
try {
return clazz.getMethod(name, paramTypes);
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
}
} else {
return null;
}
}
static boolean isAvailable() {
return pathClass != null;
}
static Iterable<?> newDirectoryStream(File dir) throws IOException {
assert pathClass != null;
try {
Object path = toPathMethod.invoke(dir);
return (Iterable<?>)newDirectoryStreamMethod.invoke(path);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof IOException)
throw (IOException)cause;
if (cause instanceof RuntimeException)
throw (RuntimeException)cause;
if (cause instanceof Error)
throw (Error)cause;
throw new AssertionError(e);
} catch (IllegalAccessException iae) {
throw new AssertionError(iae);
}
}
static String getName(Object path) {
assert pathClass != null;
try {
Object name = getNameMethod.invoke(path);
return name.toString();
} catch (InvocationTargetException e) {
throw new AssertionError(e);
} catch (IllegalAccessException iae) {
throw new AssertionError(iae);
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册