Разница между компиляцией области maven и предоставленной для JAR-упаковки
В чем разница между maven областью compile
а также provided
когда артефакт построен как JAR? Если бы это была WAR, я бы понял - артефакт будет включен или нет в WEB-INF/lib. Но в случае с JAR это не имеет значения - зависимости не включены. Они должны быть на пути к классам, когда их область действия compile
или же provided
, я знаю это provided
зависимости не транзитивны - но это только одно различие?
6 ответов
Из Maven Doc:
компилировать
Это область по умолчанию, используемая, если ни одна не указана. Зависимости компиляции доступны во всех классах пути проекта. Кроме того, эти зависимости распространяются на зависимые проекты.
предоставлена
Это очень похоже на компиляцию, но указывает, что вы ожидаете, что JDK или контейнер предоставят зависимость во время выполнения. Например, при создании веб-приложения для Java Enterprise Edition вы должны установить зависимость от API-интерфейса сервлета и связанных API-интерфейсов Java EE, так как веб-контейнер предоставляет эти классы. Эта область доступна только для пути к классам компиляции и тестирования и не является транзитивной.
Резюме:
- зависимости не транзитивны (как вы упомянули)
- предоставленная область доступна только для пути к классам компиляции и тестирования, тогда как область компиляции доступна для всех путей к классам.
- при условии, что зависимости не упакованы
Компиляция означает, что вам нужен JAR для компиляции и запуска приложения. Например, для веб-приложения JAR будет помещен в каталог WEB-INF/lib.
Предоставленный означает, что вам нужен JAR для компиляции, но во время выполнения уже существует JAR, предоставленный средой, поэтому вам не нужно, чтобы он был включен в ваше приложение. Для веб-приложения это означает, что файл JAR не будет помещен в каталог WEB-INF/lib.
Для веб-приложения, если сервер приложений уже предоставляет JAR (или его функциональность), тогда используйте "предоставленный", в противном случае используйте "compile".
Если вы планируете сгенерировать один файл JAR со всеми его зависимостями (типичный xxxx-all.jar), тогда предоставленная область имеет значение, потому что классы внутри этой области не будут упакованы в результирующий JAR.
Смотрите maven-assembly-plugin для получения дополнительной информации
- компилировать
Сделайте доступным путь к классу, не добавляйте эту зависимость в последний jar, если это обычный jar; но добавьте этот jar в jar, если final jar - это один jar (например, исполняемый jar)
- предоставлена
Зависимость будет доступна во время выполнения, поэтому ни в коем случае не добавляйте эту зависимость; даже не в одной банке (т.е. исполняемой банке и т. д.)
Вот краткое описание всех поддерживаемых зависимостей (исходный maven doc)
компилировать
Это область по умолчанию, используемая, если ни одна не указана. Зависимости компиляции доступны во всех классах пути проекта. Кроме того, эти зависимости распространяются на зависимые проекты.
предоставлена
Это очень похоже на компиляцию, но указывает, что вы ожидаете, что JDK или контейнер предоставят зависимость во время выполнения. Например, при создании веб-приложения для Java Enterprise Edition вы должны установить зависимость от API-интерфейса сервлета и связанных API-интерфейсов Java EE, так как веб-контейнер предоставляет эти классы. Эта область доступна только для пути к классам компиляции и тестирования и не является транзитивной.
время выполнения
Эта область указывает, что зависимость не требуется для компиляции, но предназначена для выполнения. Он находится во время выполнения и пути к классам теста, но не в пути к классам компиляции.
тестовое задание
Эта область указывает, что зависимость не требуется для обычного использования приложения и доступна только для фаз компиляции и выполнения теста. Эта область не является переходной.
система
Эта область похожа на предоставленную, за исключением того, что вы должны предоставить JAR, который содержит ее явно. Артефакт всегда доступен и не просматривается в хранилище.
импорт (доступен только в Maven 2.0.9 или более поздней версии)
Эта область поддерживается только для зависимости типа pom в разделе. Это указывает, что зависимость должна быть заменена действующим списком зависимостей в указанном разделе POM. Поскольку они заменяются, зависимости с областью импорта фактически не участвуют в ограничении транзитивности зависимости.
Для файла jar разница заключается в пути к классам, указанном в файле MANIFEST.MF, включенном в jar, если для addClassPath задано значение true в конфигурации maven-jar-plugin. зависимости 'compile' появятся в манифесте, зависимости 'условии' не появятся.
Одна из моих любимых мозолей состоит в том, что эти два слова должны иметь одинаковое время. Либо скомпилирован и предоставлен, либо скомпилирован и предоставлен.
Если файл jar похож на исполняемый файл jar загрузки Spring, тогда объем всех зависимостей должен быть compile
чтобы включить все файлы jar.
Но если файл jar используется в других пакетах или приложениях, тогда нет необходимости включать все зависимости в файл jar, потому что эти пакеты или приложения могут сами предоставлять другие зависимости.
Когда вы устанавливаете область maven как provided
, это означает, что при запуске плагина фактическая используемая версия зависимостей будет зависеть от установленной вами версии Apache Maven.