Можно ли смешивать --class-path и --module-path в javac (JDK 9)?
Когда я компилирую модуль, который зависит от других модулей, которые я скомпилировал ранее, я должен указать --module-path <directory>
вариант. Это делает модули, от которых я зависим, видимыми.
Но в то же время я хотел бы сделать некоторые немодульные файлы Jar видимыми. Однако, если не делать их автоматические модули, а просто указать --class-path some.jar
прямо рядом с --module-path <directory>
, тогда javac, кажется, игнорирует claspath и выдает "package yyy not found" и другие ошибки "not found".
Я могу понять, что с помощью --class-path
а также --module-path
в то же время (компиляция) является незаконной, но javac никоим образом не предупреждает меня об этом.
2 ответа
Вы можете использовать путь к классам и путь к модулям параллельно, но есть несколько деталей для рассмотрения.
Путь к модулю зависимостей ~> Путь к классу
Явные модули (JAR с дескриптором модуля на пути к модулю) не могут прочитать безымянный модуль (JAR на пути к классам) - это было сделано специально для предотвращения зависимости модульных JAR от "хаоса пути к классам".
Поскольку модуль должен требовать все свои зависимости, и они могут выполняться только другими именованными модулями (т.е. не JAR-файлами на пути к классам), все зависимости модульного JAR-файла должны быть размещены на пути к модулю. Да, даже немодульные JAR, которые затем превратятся в автоматические модули.
Интересно то, что автоматические модули могут читать безымянный модуль, поэтому их зависимости могут идти по пути классов.
Путь к классу зависимостей ~> Путь к модулю
Если вы компилируете немодульный код или запускаете приложение из немодульного JAR, система модулей все еще работает, и, поскольку немодульный код не выражает никаких зависимостей, он не будет разрешать модули из пути модуля.
Поэтому, если немодульный код зависит от артефактов на пути к модулю, вам необходимо добавить их вручную с помощью --add-modules
вариант. Не обязательно все они, только те, от которых вы напрямую зависите (система модулей будет тянуть транзитивные зависимости) - или вы можете использовать ALL-MODULE-PATH
(проверьте связанный пост, это объясняет это более подробно).
Я верю, используя --classpath
а также --module-path
Варианты при этом не являются незаконными. Можно использовать оба одновременно, даже если вы явно не указали путь к классу, по умолчанию это текущий каталог.
Подробности из javac -help
Документы по сообщениям и инструментам Javac -
--module-path <path>, -p <path>
Укажите, где искать модули приложения
--class-path <path>, -classpath <path>, -cp <path>
Укажите, где искать пользовательские файлы классов и процессоры аннотаций.
Если
--class-path
,-classpath
, или же-cp
не указаны, то путь к классу пользователя является текущим каталогом.
Изменить: Благодаря @MouseEvent, я, вероятно, пропустил часть в вопросе
Однако, если не делать их автоматическими модулями, а просто указать --class-path some.jar прямо рядом с --module-path, то javac, похоже, игнорирует claspath и выдает "package yyy not found" и прочее "not found" "ошибки.
Если вы не сделаете их автоматически, это будет считаться неназванным модульным модулем и -
Именованный модуль не может даже объявить зависимость от неназванного модуля. Это ограничение является преднамеренным, поскольку разрешение именованных модулей зависеть от произвольного содержимого пути класса сделало бы невозможной надежную конфигурацию.
Более того, неназванный модуль экспортирует все свои пакеты, поэтому код в автоматических модулях сможет получить доступ к любому общедоступному типу, загруженному из пути к классам.
Но автоматический модуль, который использует типы из classpath, не должен предоставлять эти типы явным модулям, которые зависят от него, поскольку явные модули не могут объявлять зависимости от безымянного модуля.
Если код в явном модуле
com.foo.app
относится к публичному типу вcom.foo.bar
Например, и подпись этого типа относится к типу в одном из файлов JAR, все еще находящихся в пути к классу, а затем к коду вcom.foo.app
не сможет получить доступ к этому типу, так какcom.foo.app
не может зависеть от неназванного модуля.
Это можно исправить путем лечения com.foo.app
временно как автоматический модуль, чтобы его код мог обращаться к типам из пути к классам, до тех пор, пока соответствующий файл JAR на пути к классам не будет рассматриваться как автоматический модуль или преобразован в явный модуль.