Как перечислить несистемные модули в Java 9

Обновление: я ответил на свой вопрос здесь:

Сканирование classpath/modulepath во время выполнения в Java 9

--

[Старый вопрос -- устарел:]

В системе модулей Java 9 вы можете найти системные модули, используя

Set<ModuleReference> ms = ModuleFinder.ofSystem().findAll();

Затем эти объекты ModuleReference можно использовать для отображения содержимого каждого модуля, используя:

for (ModuleReference m : ms) {
    System.out.println(m.descriptor().name());
    System.out.println(" " + m.descriptor().toNameAndVersion());
    System.out.println(" " + m.descriptor().packages());
    System.out.println(" " + m.descriptor().exports());
    Optional<URI> location = m.location();
    if (location.isPresent()) {
        System.out.println(" " + location.get()); // e.g. "jrt:/java.base"
    }
    m.open().list().forEach(s -> System.out.println("  " + s));
}

А чтобы получить модуль текущего класса, вы можете использовать

Module m = getClass().getModule();

но я не могу получить ModuleReference из этого Module (поэтому я не могу перечислить содержимое модуля, кроме пакетов), а несистемные Module не перечислены ModuleFinder.

Два вопроса:

  1. Как перечислить ресурсы в несистемных модулях?
  2. Как немодульные пути к классам читаются в JRE 9? Я просто должен полагаться на системное свойство java.class.path? (Поле AppClassLoader#ucp типа URLClassPath невидимо и заблокировано в JRE 9, поэтому вы также не можете получить его путем самоанализа.)

person Luke Hutchison    schedule 22.12.2017    source источник
comment
Я предполагаю, что выделенная часть вашего вопроса должна заключаться в том, чтобы получить URI (местоположение/путь) для модулей? тогда я предполагаю, что вас просто беспокоят несистемные модули, это правда? Поскольку все остальные атрибуты вашего кода доступны через ModuleDescriptor, который представляет собой сущность самого модуля. Также AFAIR это может быть дубликатом аналогичного вопроса. Буду ждать, пока вы подтвердите детали.   -  person Naman    schedule 22.12.2017
comment
Просто сделав слепой снимок (без подробностей в вопросе), вас может заинтересовать ModuleLayer из Module. Если вы посмотрите на пример по ссылке там, вы можете найти конфигурацию и слой, используя каталог модулей через ModuleFinder.   -  person Naman    schedule 22.12.2017


Ответы (1)


Как насчет этого:

Set<String> systemModuleNames = ModuleFinder
        .ofSystem()
        .findAll()
        .stream()
        .map(moduleRef -> moduleRef.descriptor().name())
        .collect(Collectors.toSet());

List<Module> nonSystemModules = ModuleLayer
        .boot()
        .modules()
        .stream()
        .filter(m -> !systemModuleNames.contains(m.getName()))
        .collect(Collectors.toList());

System.out.println(nonSystemModules);

Теперь, когда у вас есть nonSystemModules, вы можете делать с этим списком все, что хотите (например, получать ресурсы в каждом модуле).

person ZhekaKozlov    schedule 22.12.2017
comment
Спасибо @ЖекаКозлов. К сожалению, это не работает для автоматических (безымянных) модулей, которые, как оказалось, мне нужно обработать (в частности, автоматические модули не возвращаются ModuleLayer.boot().modules()). Вы знаете, как получить список автоматических модулей? Ре. вопрос (2): Я имею в виду возможность добавлять немодульные файлы классов в путь к классам в Java 9. Всегда ли они преобразуются в автоматические модули? Кажется, я читал, что JRE по-прежнему учитывает java.class.path и переключатель -cp. Для контекста я пытаюсь выполнить сканирование пути к классам. - person Luke Hutchison; 22.12.2017