Skip to content

Commit

Permalink
Code simplifications in JRTUtil and ClasspathJRT classes
Browse files Browse the repository at this point in the history
  • Loading branch information
HannesWell committed Apr 20, 2024
1 parent 19c1cb0 commit f4f332f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 84 deletions.
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();
static final String MODULES_SUBDIR = "/modules"; //$NON-NLS-1$
static final String[] DEFAULT_MODULE = new String[]{JAVA_BASE};
Expand All @@ -71,7 +69,6 @@ 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)
*/
Expand Down Expand Up @@ -100,28 +97,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 @@ -144,11 +119,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;

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

Expand Down Expand Up @@ -238,15 +211,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 @@ -363,7 +336,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 @@ -373,19 +346,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 @@ -401,7 +374,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 @@ -436,21 +409,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, 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 @@ -479,21 +451,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 @@ -511,8 +483,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 All @@ -531,8 +503,7 @@ public static JrtFileSystem getNewJrtFileSystem(Jdk jdk, String release) throws
this.jdk = jdkHome;
this.release = release;
JRTUtil.MODULE_TO_LOAD = System.getProperty("modules.to.load"); //$NON-NLS-1$
HashMap<String, String> env = new HashMap<>();
env.put("java.home", this.jdk.path); //$NON-NLS-1$
Map<String, String> env = Map.of("java.home", this.jdk.path.toString()); //$NON-NLS-1$
this.fs = FileSystems.newFileSystem(JRTUtil.JRT_URI, env);
this.modRoot = this.fs.getPath(JRTUtil.MODULES_SUBDIR);
// Set up the root directory where modules are located
Expand Down Expand Up @@ -697,16 +668,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 @@ -719,15 +690,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 @@ -743,7 +714,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 @@ -16,6 +16,7 @@
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

Expand All @@ -25,7 +26,7 @@
*/
class SoftClassCache {

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

void clear() {
this.jdks.clear();
Expand All @@ -37,9 +38,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
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collection;
import java.util.Collections;
Expand All @@ -29,7 +29,6 @@

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
Expand Down Expand Up @@ -74,10 +73,9 @@ public ClasspathJrtWithReleaseOption(String zipFilename, AccessRuleSet accessRul
}
this.release = getReleaseOptionFromCompliance(release);
try {
this.ctSym = JRTUtil.getCtSym(Paths.get(this.zipFilename).getParent().getParent());
this.ctSym = JRTUtil.getCtSym(Path.of(this.zipFilename).getParent().getParent());
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, ClasspathJrtWithReleaseOption.class,
"Failed to init ct.sym for " + this.zipFilename, e)); //$NON-NLS-1$
throw new CoreException(Status.error("Failed to init ct.sym for " + this.zipFilename, e)); //$NON-NLS-1$
}
initialize();
loadModules();
Expand All @@ -98,8 +96,7 @@ private String getReleaseOptionFromCompliance(String comp) throws CoreException
if (comp.indexOf('.') == -1) {
return comp;
}
throw new CoreException(new Status(IStatus.ERROR, ClasspathJrtWithReleaseOption.class,
"Invalid value for --release argument:" + comp)); //$NON-NLS-1$
throw new CoreException(Status.error("Invalid value for --release argument:" + comp)); //$NON-NLS-1$
}
}

Expand All @@ -121,7 +118,7 @@ protected void initialize() throws CoreException {

if (!Files.exists(this.releasePath.resolve(this.releaseCode))) {
Exception e = new IllegalArgumentException("release " + this.release + " is not found in the system"); //$NON-NLS-1$//$NON-NLS-2$
throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, e.getMessage(), e));
throw new CoreException(Status.error(e.getMessage(), e));
}
if (Files.exists(this.fs.getPath(this.releaseCode, "system-modules"))) { //$NON-NLS-1$
this.fs = null; // Fallback to default version, all classes are on jrt fs, not here.
Expand All @@ -137,16 +134,16 @@ Map<String, SimpleSet> findPackagesInModules() {
if (this.modPathString == null) {
return Map.of();
}
Map<String, SimpleSet> cache = PackageCache.computeIfAbsent(this.modPathString, key -> {
return PackageCache.computeIfAbsent(this.modPathString, key -> {
final Map<String, SimpleSet> packagesInModule = new HashMap<>();
try {
JRTUtil.walkModuleImage(this.jrtFile, this.release, new JrtPackageVisitor(packagesInModule), JRTUtil.NOTIFY_PACKAGES | JRTUtil.NOTIFY_MODULES);
JRTUtil.walkModuleImage(this.jrtFile, this.release, new JrtPackageVisitor(packagesInModule),
JRTUtil.NOTIFY_PACKAGES | JRTUtil.NOTIFY_MODULES);
} catch (IOException e) {
Util.log(e, "Failed to init packages for " + this.modPathString); //$NON-NLS-1$
}
return packagesInModule.isEmpty() ? null : Collections.unmodifiableMap(packagesInModule);
});
return cache;
}

public void loadModules() {
Expand All @@ -162,7 +159,7 @@ public void loadModules() {
Map<String, IModule> newCache = new HashMap<>();
for (Path root : releaseRoots) {
try {
Files.walkFileTree(root, Collections.emptySet(), 2, new JRTUtil.AbstractFileVisitor<Path>() {
Files.walkFileTree(root, Collections.emptySet(), 2, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path f, BasicFileAttributes attrs) throws IOException {
if (attrs.isDirectory() || f.getNameCount() < 3) {
Expand Down

0 comments on commit f4f332f

Please sign in to comment.