Зависимости автоматического модуля Java 9 не могут быть разрешены / модуль не найден

Я пытаюсь перенести некоторые устаревшие приложения на новую систему модулей Java 9, чтобы усилить ее инкапсуляцию.

Я начинаю извне, предполагая, что у классов на периферии будут наименьшие внешние зависимости.

Как и следовало ожидать, я объявил очень открытый модуль для начала:

module com.example.user {   
    exports com.example.user;
}

Это мгновенно разрушает весь проект (внутри всех классов), когда внезапно перестает разрешаться каждый импорт для внешней зависимости (вызывая проблемы с Java более 1 тыс.):

Импорт com.otherexample не может быть решен

Импорт org.springframework не может быть решен

и т.п.

Локальные пакеты в одном проекте com.example.price все еще работаю - как делаю java.util и т.п.

Все внешние зависимости (были) управляются с помощью Maven. В пути сборки (проект Eclipse) я все еще вижу их как зависимости "Classpath" - но только системные библиотеки JRE в "Modulepath".

Могут ли две концепции сосуществовать? В настоящее время кажется, что с одним module-info.java где-нибудь в проекте все зависимости classpath перестают работать?

Я читал об использовании автоматических модулей, что, похоже, подразумевало, что вы можете использовать устаревшие / немодульные файлы jar, включив их в путь к модулям, а затем сослаться на них по имени файла. Они используют пример:

module com.foo.myapp {
  requires guava;  // guava not yet modularised, so use the filename
}

Я не смог найти много другой информации, но это, кажется, соответствует соглашению, которое Eclipse использует, когда он автоматически генерирует module-info.java, например:

spring-core-4.3.8.RELEASE.jar

будет выглядеть так:

requires spring.core;

Однако это все еще приводит к ошибке Java, о которой сообщает Eclipse:

spring.core не может быть преобразован в модуль

Maven сообщает:

[ERROR] module-info.java:[39,16] error: module not found: spring.core

... и каждый класс в проекте с внешней зависимостью все еще не работает.

1 ответ

Решение

Спасибо Robert Scholte Шолте ( Robert Scholte за указание на обновленный maven-compiler-plugin 3.7.0 (я использовал 3.6.1), это действительно очистило вывод командной строки цели компиляции (со спецификой Java 9), чтобы помочь мне добраться до маршрут проблемы. Это сузило количество сообщений об ошибках от каждого requires давая мне ошибку:

[WARNING] ********************************************************************************************************************
[WARNING] * Required filename-based automodules detected. Please don't publish this project to a public artifact repository! *
[WARNING] ********************************************************************************************************************
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 56 source files to ./target/classes
~~~ snip ~~~
[ERROR] module-info.java error: module not found: foo.bar

Соответствие затмению:

foo.bar cannot be resolved to a module

Ошибки появляются только для шести автоматических модулей / библиотек (jar), а не для всех (24). Отлично.

В моем POM я бы разделил вывод исходных каталогов на их собственные выходные каталоги (target/classes). Тем не менее, как module-info.java ссылаются на зависимости (такие как requires spring.core;), которые не используются / на которые не ссылается код (классы) в этой папке - он не может их разрешить.

Зачем? Базовое управление зависимостями Maven - я бы выделил эти библиотеки за пределы цели по умолчанию (чтобы соответствовать разделению выходных каталогов).

Довольно простой результат - но я думаю, что я не буду единственным человеком, который столкнется с этим, поскольку Java начинает посягать на некоторые аспекты управления зависимостями, которые пересекаются с традиционным использованием Maven.

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