我能在 JAVA-HOME/lib 中找到的唯一 jar文件是一个名为jrt-fs.jar的文件,它的大小只有 105 KB。
那么运行时(引导程序)类在哪里呢?
我正在尝试使用如何提取文件 jre-9/lib/modules?.
该解决方案有效,但似乎分配给读取 Java 运行时映像内容的资源从未被释放,从而导致内存泄漏,例如可以通过 VisualVM 观察到:
如何修复以下再现中的内存泄漏?
package leak;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Stream;
public class JrtfsLeak {
public static void main(String[] args) throws Exception {
Path javaHome = Paths.get(args[0]);
for (int i = 0; i < 100000; ++i) {
modules(javaHome).close();
}
}
private static Stream<Path> modules(Path javaHome) throws Exception {
Map<String, String> env = Collections.singletonMap("java.home", javaHome.toString());
Path jrtfsJar = …Run Code Online (Sandbox Code Playgroud) 从 Java 11 开始,如何读取另一个运行时映像的内容?
为了列出 Java 运行时映像的内容,JEP 220建议了以下解决方案:
URL 方案的内置 NIO
FileSystem提供程序jrt确保开发工具可以通过加载FileSystemURL 命名的来枚举和读取运行时映像中的类和资源文件jrt:/,如下所示:Run Code Online (Sandbox Code Playgroud)FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); byte[] jlo = Files.readAllBytes(fs.getPath("modules", "java.base", "java/lang/Object.class"));
此代码段有效,并允许我读取java/lang/Object.class正在执行代码的 Java 安装的运行时映像中的内容。
java/lang/Object.class考虑到它的 java home,我怎样才能让它读取另一个 Java 安装中的内容?
我已经阅读了这个 SO answer,它解释了如何从 Java 8 运行时读取 Java 运行时图像的内容。不幸的是,这不适用于较新的 Java 运行时,因为我相信 for 的文件系统jrt:/将始终指向当前的运行时映像。
我正在尝试从java.baseas 中读取类InputStream。我已经有一种方法可以读取给定File对象的类文件,但是我无法获取File对象,因为我使用的是 JDK 11 并且不再有rt.jar文件了。按照这个答案之后,我大致有以下代码(我使用的是 Scala,但这本质上是一个关于 Java 的问题,因此是标签):
val fs = FileSystems.newFileSystem(URI.create("jrt:/"), Collections.emptyMap, loader)
Files.list(fs.getPath("/modules")).forEach { mdl =>
Files.walk(mdl).forEach { (classFile: Path) =>
val asFile = classFile.toAbsolutePath.toFile //Here's where I get an exception
//do stuff with that
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我使用classFile.toFileor 时classFile.toAbsolutePath.toFile,我得到一个UnsupportedOperationException,我猜这是因为它不是物理文件。但是,我需要一个File对象变成一个InputStream并读取。如何获取File属于 JDK 的某个模块(或每个模块)中每个类文件的对象?