【问题标题】:How to extract the file jre-9/lib/modules?如何提取文件 jre-9/lib/modules?
【发布时间】:2018-03-08 09:24:09
【问题描述】:

JRE-9/lib 目录中(至少在Windows 上),有一个名为modules 的新文件,其大小约为107 MB。是否可以提取该文件或列出其中的 java 模块?

我可以看到jdk-9/bin/jmod.exe 提供了一个名为jmod 的新工具,但它用于读取位于jdk-9/jmods.jmod 文件,它无法读取文件modules

【问题讨论】:

    标签: java java-9 java-module jdk-tools jmod


    【解决方案1】:

    modules 文件是一个容器文件。它是 JDK 内部的,格式没有记录(它可能随时更改)。为了解决问题,可以使用 bin 目录中的jimage 工具列出或提取内容。

    【讨论】:

    • 任何指向jimage 的链接以及如何使用它也会很有用。
    • 没有 jimage 的文档页面,但 jimage --help 应该足够了。请注意,该工具用于故障排除/支持使用,大多数开发人员都不需要它。
    • 为我工作。刚刚做了$ jimage extract $JAVA_HOME/lib/modules 和噗!
    【解决方案2】:

    运行时资源以向后兼容的方式处理。例如。当你这样做的时候

    URL url = Object.class.getResource("Object.class");
    System.out.println(url);
    

    在过去,你通常会得到类似的东西

    jar:file:/path-to-jre/lib/rt.jar!/java/lang/Object.class
    

    在 Java 9 下运行同样的程序会给你

    jrt:/java.base/java/lang/Object.class
    

    相反。无论哪种情况,您都可以在其上打开 FileSystem 以检查其他可用资源(自 Java 7 起)。虽然ZipFileSystem 必须首先通过FileSystems.newFileSystem 创建,但Java 9 的文件系统甚至已经开放使用:

    private static void readMyOwnJRE() throws IOException {
        try {
            Path p = Paths.get(URI.create("jrt:/")).resolve("/modules");
            System.out.println("My own JRE's modules:");
            Files.list(p).forEach(m -> System.out.println(m.getFileName()));
            System.out.println();
        } catch(FileSystemNotFoundException ex) {
            System.out.println("Could not read my modules (perhaps not Java 9?).");
        }
    }
    

    如果您在与要检查的 JRE 不同的 JRE 下运行,则必须首先手动加载适当的文件系统实现,但这为检查 Java 9 安装提供了可能性,即使是从 Java 8 JRE 中检查:

    public static void readOtherJRE(Path pathToJRE) throws IOException {
        Path p = pathToJRE.resolve("lib").resolve("jrt-fs.jar");
        if(Files.exists(p)) {
            try(URLClassLoader loader = new URLClassLoader(new URL[]{ p.toUri().toURL() });
                FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
                                                          Collections.emptyMap(),
                                                          loader)) {
                System.out.println("Modules of "+pathToJRE);
                Files.list(fs.getPath("/modules")).forEach(System.out::println);
                System.out.println();
            }
        }
    }
    

    一旦你有了一个文件系统(或一个Path),你就可以使用所有的标准功能,例如Files 检查或提取/复制数据,尽管正确的术语是“将等效的类文件存储在不同的文件系统中”,因为运行时映像的表示根本不必是类文件。

    【讨论】:

    【解决方案3】:

    modules 文件是一个单独的文件(不打算在任何地方提取),其中包含 JDK 中存在的所有模块的二进制表示,采用非文档格式,可能会发生变化。您可以使用java --list-modules 列出它包含的模块。

    最初,modules 文件将包含每个模块,并且基本上是 JDK 本身的两倍,但是一旦您使用 jlink 实用程序“缩小”您的 JDK,modules 文件将变得更小(假设您的程序包含随 JDK 提供的模块的子集)。有关jlink 的更多信息,请参见此处:http://openjdk.java.net/jeps/282

    【讨论】:

    • 如果开发人员打算将 JDK 缩小,为什么不进行缩小?
    【解决方案4】:

    您可以通过java --list-modules列出模块

    【讨论】:

      【解决方案5】:

      你可以使用

      $ jimage list $JAVA_HOME/lib/modules
      

      列出所有系统包的名称,如“java/io/EOFException.class”等

      你也可以用

      $ jimage extract --dir=<directory>  $JAVA_HOME/lib/modules
      

      将所有.class文件解压到指定目录。

      参考:https://adoptopenjdk.gitbooks.io/adoptopenjdk-getting-started-kit/en/intermediate-steps/openjdk9-jimage.html

      【讨论】:

        【解决方案6】:

        你可以使用 libjimage 来读取这个文件。

        【讨论】:

          猜你喜欢
          • 2016-08-09
          • 2022-10-13
          • 1970-01-01
          • 1970-01-01
          • 2015-12-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多