6894534: SeedGenerator shouldn't require java.nio.file to be present
Reviewed-by: alanb
--- a/jdk/src/share/classes/sun/security/provider/SeedGenerator.java Thu Oct 29 19:55:52 2009 -0700
+++ b/jdk/src/share/classes/sun/security/provider/SeedGenerator.java Fri Oct 30 11:28:42 2009 +0800
@@ -63,13 +63,13 @@
* @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 @@
// 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());
+ try {
+ for (Object entry: stream) {
+ if (count < 512 || r.nextBoolean()) {
+ md.update(NIODirectoryStream.getName(
+ entry).getBytes());
+ }
+ if (count++ > 1024) {
+ break;
+ }
}
- if (count++ > 1024) {
- break;
- }
+ } finally {
+ ((Closeable)stream).close();
}
- } finally {
- ds.close();
+ } else {
+ String[] sa = f.list();
+ for(int i = 0; i < sa.length; i++) {
+ md.update(sa[i].getBytes());
+ }
}
} catch (Exception ex) {
md.update((byte)ex.hashCode());
@@ -505,4 +517,76 @@
}
+ /**
+ * 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);
+ }
+ }
+ }
}
+