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 22, 2024
1 parent f53ffcb commit c5068c1
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 c5068c1

Please sign in to comment.