Как извлечь файл jre-9/lib/modules?

на JRE-9/lib каталог (по крайней мере, в Windows), есть новый файл под названием modules, размер которого составляет около 107 МБ. Можно ли извлечь этот файл или, возможно, перечислить в нем модули java?

Я вижу, что новый инструмент под названием jmod находится в jdk-9/bin/jmod.exe, но это для чтения .jmod файлы, которые расположены по адресу jdk-9/jmods и он не может прочитать файл modules.

5 ответов


на modules файл-это файл контейнера. Он является внутренним для JDK, и формат не документирован (он может измениться в любое время). Для устранения неполадок,jimage инструмент в каталоге bin можно использовать для списка или извлечения содержимого.


ресурсы среды выполнения обрабатываются обратно совместимым способом. Е. Г. когда ты сделал

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:/modules"));
        System.out.println("My own JRE's modules:");
        Files.list(p).forEach(System.out::println);
        System.out.println();
    } catch(FileSystemNotFoundException ex) {
        System.out.println("Could not read my modules (perhaps not Java 9?).");
    }
}

если вы работаете под другим 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 для проверки или извлечения / копирования данных, хотя правильный термин было бы "хранить эквивалентный файл класса" в другой файловой системе, поскольку представление образа среды выполнения не должно быть файлом класса вообще.


на modules файл предназначен для одного файла (не предназначен для извлечения в любом месте), который содержит двоичное представление всех модулей, присутствующих в JDK в формате undocument, который может быть изменен. Вы можете перечислить модули, которые он содержит, с помощью java --list-modules.

изначально modules файл будет содержать каждый модуль и в основном удваивать сторону JDK самостоятельно, но как только вы "уменьшите" свой JDK, используя jlink программы будет меньше (предполагая, что ваша программа содержит подмножество модулей, предоставленных с JDK). Для получения дополнительной информации о jlink смотрите здесь: http://openjdk.java.net/jeps/282


вы можете перечислить модули через java --list-modules


вы можете использовать libjimage для чтения этого файла.