Как распаковать файл 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, в недокументированном формате, который может быть изменен. Вы можете перечислить модули, которые он содержит java --list-modules,

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

Вы можете использовать

$ 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

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

Вы можете использовать libjimage, чтобы прочитать этот файл.

Другие вопросы по тегам