Skip to content

Commit

Permalink
Code simplifications in JRTUtil and ClasspathJRT classes
Browse files Browse the repository at this point in the history
And ensure that the real fully resolved path of a resource is used as
key of a cache.
  • Loading branch information
HannesWell authored and iloveeclipse committed Apr 23, 2024
1 parent c0bffa4 commit 523d582
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand All @@ -42,7 +43,7 @@

public class JrtFileSystem extends Archive {

public HashMap<String, Path> modulePathMap;
Map<String, Path> modulePathMap;
Path modules;
private java.nio.file.FileSystem jrtfs;

Expand All @@ -55,7 +56,7 @@ public void initialize() throws IOException {
// initialize packages
this.modulePathMap = new HashMap<>();
if (this.file.exists()) {
this.jrtfs = JRTUtil.getJrtFileSystem(this.file.getAbsolutePath());
this.jrtfs = JRTUtil.getJrtFileSystem(this.file.toPath());
this.modules = this.jrtfs.getPath(JRTUtil.MODULES_SUBDIR);
} else {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,7 @@ class SystemLocationContainer extends LocationContainer {
public SystemLocationContainer(Location loc, JrtFileSystem jrt) throws IOException {
super(loc);
jrt.initialize();
HashMap<String, Path> modulePathMap = jrt.modulePathMap;
Set<String> keySet = modulePathMap.keySet();
Set<String> keySet = jrt.modulePathMap.keySet();
for (String mod : keySet) {
Path path = jrt.file.toPath();
ModuleLocationWrapper wrapper = new ModuleLocationWrapper(loc, mod, false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
Expand All @@ -28,12 +27,11 @@
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.ProviderNotFoundException;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -54,7 +52,7 @@ public class JRTUtil {
public static final boolean DISABLE_CACHE = Boolean.getBoolean("org.eclipse.jdt.disable_JRT_cache"); //$NON-NLS-1$
public static final boolean PROPAGATE_IO_ERRORS = Boolean.getBoolean("org.eclipse.jdt.propagate_io_errors"); //$NON-NLS-1$

public static final String JAVA_BASE = "java.base".intern(); //$NON-NLS-1$
public static final String JAVA_BASE = "java.base"; //$NON-NLS-1$
public static final char[] JAVA_BASE_CHAR = JAVA_BASE.toCharArray();
public static final String MODULES_SUBDIR = "/modules"; //$NON-NLS-1$
static final String[] DEFAULT_MODULE = new String[]{JAVA_BASE};
Expand All @@ -71,12 +69,11 @@ public class JRTUtil {

// TODO: Java 9 Think about clearing the cache too.
private static Map<String, JrtFileSystem> images = new ConcurrentHashMap<>();

/**
* Map from JDK home path to ct.sym file (located in /lib in the JDK)
*/
private static final Map<Path, CtSym> ctSymFiles = new ConcurrentHashMap<>();
private static final Map<String, FileSystem> JRT_FILE_SYSTEMS = new ConcurrentHashMap<>();
private static final Map<Path, FileSystem> JRT_FILE_SYSTEMS = new ConcurrentHashMap<>();

static final SoftClassCache classCache = new SoftClassCache();

Expand All @@ -101,28 +98,6 @@ public default FileVisitResult visitModule(T path, String name) throws IOExcepti
}
}

public static abstract class AbstractFileVisitor<T> implements FileVisitor<T> {
@Override
public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(T file, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFileFailed(T file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult postVisitDirectory(T dir, IOException exc) throws IOException {
return FileVisitResult.CONTINUE;
}
}

/**
* @param image the path to the root of the JRE whose libraries we are interested in.
* @return may return {@code null}
Expand All @@ -145,10 +120,9 @@ public static JrtFileSystem getJrtSystem(File image) {
*/
public static JrtFileSystem getJrtSystem(File image, String release) throws IOException {
Jdk jdk = new Jdk(image);
String key = jdk.path;

String key = jdk.path.toString();
if (release != null && !jdk.sameRelease(release)) {
key = key + "|" + release; //$NON-NLS-1$
key += "|" + release; //$NON-NLS-1$
}
try {
JrtFileSystem system = images.computeIfAbsent(key, x -> {
Expand All @@ -163,7 +137,7 @@ public static JrtFileSystem getJrtSystem(File image, String release) throws IOEx
});
return system;
} catch (RuntimeIOException e) {
throw e.getCause();
throw e.getCause();
}
}

Expand All @@ -174,11 +148,11 @@ public static JrtFileSystem getJrtSystem(File image, String release) throws IOEx
* @throws IOException
* on any error
*/
public static FileSystem getJrtFileSystem(String path) throws IOException {
public static FileSystem getJrtFileSystem(Path path) throws IOException {
try {
FileSystem fs = JRT_FILE_SYSTEMS.computeIfAbsent(path, p -> {
FileSystem fs = JRT_FILE_SYSTEMS.computeIfAbsent(path.toRealPath(), p -> {
try {
return FileSystems.newFileSystem(JRTUtil.JRT_URI, Map.of("java.home", p)); //$NON-NLS-1$
return FileSystems.newFileSystem(JRTUtil.JRT_URI, Map.of("java.home", p.toString())); //$NON-NLS-1$
} catch (IOException e) {
throw new RuntimeIOException(e);
}
Expand Down Expand Up @@ -222,7 +196,7 @@ public static FileSystem getJarFileSystem(Path path) throws IOException {
public static CtSym getCtSym(Path jdkHome) throws IOException {
CtSym ctSym;
try {
ctSym = ctSymFiles.compute(jdkHome, (Path x, CtSym current) -> {
ctSym = ctSymFiles.compute(jdkHome.toRealPath(), (Path x, CtSym current) -> {
if (current == null || !current.getFs().isOpen()) {
try {
return new CtSym(x);
Expand Down Expand Up @@ -261,15 +235,15 @@ public static void reset() {
* @param visitor an instance of JrtFileVisitor to be notified of the entries in the JRT image.
* @param notify flag indicating the notifications the client is interested in.
*/
public static void walkModuleImage(File image, final JRTUtil.JrtFileVisitor<java.nio.file.Path> visitor, int notify) throws IOException {
public static void walkModuleImage(File image, final JRTUtil.JrtFileVisitor<Path> visitor, int notify) throws IOException {
JrtFileSystem system = getJrtSystem(image, null);
if (system == null) {
return;
}
system.walkModuleImage(visitor, notify);
}

public static void walkModuleImage(File image, String release, final JRTUtil.JrtFileVisitor<java.nio.file.Path> visitor, int notify) throws IOException {
public static void walkModuleImage(File image, String release, final JRTUtil.JrtFileVisitor<Path> visitor, int notify) throws IOException {
JrtFileSystem system = getJrtSystem(image, release);
if (system == null) {
return;
Expand Down Expand Up @@ -386,7 +360,7 @@ class JrtFileSystemWithOlderRelease extends JrtFileSystem {
JrtFileSystemWithOlderRelease(Jdk jdkHome, String release) throws IOException {
super(jdkHome, release);
String releaseCode = CtSym.getReleaseCode(this.release);
this.ctSym = JRTUtil.getCtSym(Paths.get(this.jdk.path));
this.ctSym = JRTUtil.getCtSym(this.jdk.path);
this.fs = this.ctSym.getFs();
if (!Files.exists(this.fs.getPath(releaseCode))
|| Files.exists(this.fs.getPath(releaseCode, "system-modules"))) { //$NON-NLS-1$
Expand All @@ -396,19 +370,19 @@ class JrtFileSystemWithOlderRelease extends JrtFileSystem {
}

@Override
void walkModuleImage(final JRTUtil.JrtFileVisitor<java.nio.file.Path> visitor, final int notify) throws IOException {
void walkModuleImage(final JRTUtil.JrtFileVisitor<Path> visitor, final int notify) throws IOException {
for (Path p : this.releaseRoots) {
Files.walkFileTree(p, new JRTUtil.AbstractFileVisitor<java.nio.file.Path>() {
Files.walkFileTree(p, new SimpleFileVisitor<>() {
@Override
public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs)
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
int count = dir.getNameCount();
if (count == 1) {
return FileVisitResult.CONTINUE;
}
if (count == 2) {
// e.g. /9A/java.base
java.nio.file.Path mod = dir.getName(1);
Path mod = dir.getName(1);
if ((JRTUtil.MODULE_TO_LOAD != null && JRTUtil.MODULE_TO_LOAD.length() > 0
&& JRTUtil.MODULE_TO_LOAD.indexOf(mod.toString()) == -1)) {
return FileVisitResult.SKIP_SUBTREE;
Expand All @@ -424,7 +398,7 @@ public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttrib
}

@Override
public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs)
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
if ((notify & JRTUtil.NOTIFY_FILES) == 0) {
return FileVisitResult.CONTINUE;
Expand Down Expand Up @@ -459,21 +433,20 @@ public synchronized IOException getCause() {
}

class Jdk {
final String path;
final Path path;
final String release;
static final Map<String, String> pathToRelease = new ConcurrentHashMap<>();
private static final Map<Path, String> pathToRelease = new ConcurrentHashMap<>();

public Jdk(File jrt) throws IOException {
this.path = toJdkHome(jrt);
try {
String rel = pathToRelease.computeIfAbsent(this.path, key -> {
this.release = pathToRelease.computeIfAbsent(this.path.toRealPath(), p -> {
try {
return readJdkReleaseFile(this.path);
return readJdkReleaseFile(p);
} catch (IOException e) {
throw new RuntimeIOException(e);
}
});
this.release = rel;
} catch (RuntimeIOException rio) {
throw rio.getCause();
}
Expand Down Expand Up @@ -502,21 +475,21 @@ boolean sameRelease(String other) {
return Long.compare(jdkLevel, otherJdkLevel) == 0;
}

static String toJdkHome(File jrt) {
String home;
static Path toJdkHome(File jrt) {
Path home;
Path normalized = jrt.toPath().normalize();
if (jrt.getName().equals(JRTUtil.JRT_FS_JAR)) {
home = normalized.getParent().getParent().toString();
home = normalized.getParent().getParent();
} else {
home = normalized.toString();
home = normalized;
}
return home;
}

static String readJdkReleaseFile(String javaHome) throws IOException {
static String readJdkReleaseFile(Path javaHome) throws IOException {
Properties properties = new Properties();
try(FileReader reader = new FileReader(new File(javaHome, "release"))){ //$NON-NLS-1$
properties.load(reader);
try (InputStream in = Files.newInputStream(javaHome.resolve("release"))) { //$NON-NLS-1$
properties.load(in);
}
// Something like JAVA_VERSION="1.8.0_05"
String ver = properties.getProperty("JAVA_VERSION"); //$NON-NLS-1$
Expand All @@ -534,8 +507,8 @@ class JrtFileSystem {
private final Map<String, List<String>> packageToModules = new HashMap<>();

FileSystem fs;
Path modRoot;
Jdk jdk;
final Path modRoot;
final Jdk jdk;
final String release;

public static JrtFileSystem getNewJrtFileSystem(Jdk jdk, String release) throws IOException {
Expand Down Expand Up @@ -718,16 +691,16 @@ public ClassFileReader getClassfile(String fileName, String module) throws IOExc
}

void walkJrtForModules() throws IOException {
Iterable<java.nio.file.Path> roots = this.fs.getRootDirectories();
for (java.nio.file.Path path : roots) {
try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(path)) {
for (final java.nio.file.Path subdir: stream) {
Iterable<Path> roots = this.fs.getRootDirectories();
for (Path path : roots) {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
for (final Path subdir: stream) {
if (!subdir.toString().equals(JRTUtil.MODULES_SUBDIR)) {
Files.walkFileTree(subdir, new JRTUtil.AbstractFileVisitor<java.nio.file.Path>() {
Files.walkFileTree(subdir, new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs) throws IOException {
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
// e.g. /modules/java.base
java.nio.file.Path relative = subdir.relativize(file);
Path relative = subdir.relativize(file);
cachePackage(relative.getParent().toString(), relative.getFileName().toString());
return FileVisitResult.CONTINUE;
}
Expand All @@ -740,15 +713,15 @@ public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes at
}
}

void walkModuleImage(final JRTUtil.JrtFileVisitor<java.nio.file.Path> visitor, final int notify) throws IOException {
Files.walkFileTree(this.modRoot, new JRTUtil.AbstractFileVisitor<java.nio.file.Path>() {
void walkModuleImage(final JRTUtil.JrtFileVisitor<Path> visitor, final int notify) throws IOException {
Files.walkFileTree(this.modRoot, new SimpleFileVisitor<>() {
@Override
public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs) throws IOException {
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
int count = dir.getNameCount();
if (count == 1) return FileVisitResult.CONTINUE;
if (count == 2) {
// e.g. /modules/java.base
java.nio.file.Path mod = dir.getName(1);
Path mod = dir.getName(1);
if ((JRTUtil.MODULE_TO_LOAD != null && JRTUtil.MODULE_TO_LOAD.length() > 0 &&
JRTUtil.MODULE_TO_LOAD.indexOf(mod.toString()) == -1)) {
return FileVisitResult.SKIP_SUBTREE;
Expand All @@ -764,7 +737,7 @@ public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttrib
}

@Override
public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs) throws IOException {
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if ((notify & JRTUtil.NOTIFY_FILES) == 0)
return FileVisitResult.CONTINUE;
int count = file.getNameCount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
*/
class SoftClassCache {

private final ConcurrentMap<String, JdkClasses> jdks = new ConcurrentHashMap<>();
private final ConcurrentMap<Path, JdkClasses> jdks = new ConcurrentHashMap<>();

void clear() {
this.jdks.clear();
Expand All @@ -37,9 +37,9 @@ public byte[] getClassBytes(Jdk jdk, Path path) throws IOException {

private static final class JdkClasses {
private final ConcurrentMap<Path, ClassBytes> classes = new ConcurrentHashMap<>(10007);
private final String jdkPath;
private final Path jdkPath;

public JdkClasses(String jdkPath) {
public JdkClasses(Path jdkPath) {
this.jdkPath = jdkPath;
}

Expand Down
Loading

0 comments on commit 523d582

Please sign in to comment.