8066753: OptimisticTypePersistence.java should work properly with "jrt" URL
Reviewed-by: lagergren, attila
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Fri Dec 05 14:35:00 2014 +0530
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Fri Dec 05 19:01:26 2014 +0530
@@ -30,13 +30,18 @@
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.io.UncheckedIOException;
+import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.security.AccessController;
import java.security.MessageDigest;
@@ -49,6 +54,7 @@
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Predicate;
@@ -389,8 +395,7 @@
return "dev-" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(getLastModifiedClassFile(
dir, 0L)));
} else if(protocol.equals("jrt")) {
- // FIXME: revisit this for a better option with jrt
- return "jrt";
+ return getJrtVersionDirName();
} else {
throw new AssertionError();
}
@@ -549,4 +554,44 @@
}
return Math.max(0, Integer.parseInt(str));
}
+
+ // version directory name if nashorn is loaded from jrt:/ URL
+ private static String getJrtVersionDirName() throws Exception {
+ final FileSystem fs = getJrtFileSystem();
+ // consider all .class resources under nashorn module to compute checksum
+ final Path nashorn = fs.getPath("/jdk.scripting.nashorn");
+ if (! Files.isDirectory(nashorn)) {
+ throw new FileNotFoundException("missing /jdk.scripting.nashorn dir in jrt fs");
+ }
+ final MessageDigest digest = MessageDigest.getInstance("SHA-1");
+ Files.walk(nashorn).forEach(new Consumer<Path>() {
+ @Override
+ public void accept(Path p) {
+ // take only the .class resources.
+ if (Files.isRegularFile(p) && p.toString().endsWith(".class")) {
+ try (final InputStream in = Files.newInputStream(p)) {
+ // get actual (uncompressed) size from file attribute
+ final int sz = ((Number)Files.getAttribute(p, "size")).intValue();
+ final byte[] buf = new byte[sz];
+ in.read(buf);
+ digest.update(buf);
+ } catch (final IOException ioe) {
+ throw new UncheckedIOException(ioe);
+ }
+ }
+ }
+ });
+ return Base64.getUrlEncoder().withoutPadding().encodeToString(digest.digest());
+ }
+
+ // get the default jrt FileSystem instance
+ private static FileSystem getJrtFileSystem() {
+ return AccessController.doPrivileged(
+ new PrivilegedAction<FileSystem>() {
+ @Override
+ public FileSystem run() {
+ return FileSystems.getFileSystem(URI.create("jrt:/"));
+ }
+ });
+ }
}