2009-09-08 5 views
14

Скажем, у меня есть две зависимости Maven, определенные в проекте, как показано ниже.Зависимость Maven в зависимости от другой области

<dependency> 
     <groupId>com.thoughtworks.xstream</groupId> 
     <artifactId>xstream</artifactId> 
     <version>1.3.1</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>mycompany.library</groupId> 
     <artifactId>mylibrary</artifactId> 
     <version>1.0.1</version> 
     <scope>compile</scope> 
    </dependency> 

Затем, в пределах моей библиотеки, у меня также есть зависимость, определенная ниже.

<dependency> 
     <groupId>com.thoughtworks.xstream</groupId> 
     <artifactId>xstream</artifactId> 
     <version>1.3.1</version> 
     <scope>compile</scope> 
    </dependency> 

Когда я упаковываю свой проект, я не вижу xstream, упакованного внутри него. Я думаю, что область зависимости xstream проекта, «тест», переопределяет область зависимости xstream mylibrary, «компилирует».

В такой ситуации, как лучше всего включить xstream для всего проекта, чтобы подмодуль мог иметь к нему доступ при упаковке в проекте?

Я читал объяснение веб-сайта Apache Maven в отношении транзитивных зависимостей, но я изо всех сил пытаюсь понять, что это значит, а также узнать о лучшей практике в этой ситуации.

ответ

11

Это действительно странно для меня, и если это «функция», я думаю, что это является действительно опасным. Во всяком случае, это не ошибка Maven, и она находится в документации maven here.

Что касается лучших практик в этой проблеме, я ничего не слышал, но самый безопасный способ - полностью удалить xstream от вашего pom, опираясь на транзитивную зависимость. Это приведет к сбою сборки при удалении зависимости от mylibrary. Это станет уведомлением о том, что вам нужно что-то исправить. Вы не будете свободно освобождать требуемые зависимости, и у вас не будет никаких зависимостей, которые вам больше не нужны.

На стороне примечание, зависимость mvn: анализ может использоваться для проверки зависимостей, которые включены, но не используются.

0

Если вы хотите его упаковать, почему вы объявляете область? Если это необходимо во время компиляции и выполнения, не следует ли оставить область пустым? Если вы это сделали, вам понадобится только

<dependency> 
    <groupId>mycompany.modules</groupId> 
    <artifactId>submodule</artifactId> 
    <version>1.0.1</version> 
</dependency> 

в вашей пом. Разве есть причина, по которой его можно отскочить во время компиляции, но не во время упаковки?

+0

с сайта Apache Maven: - compile Это область по умолчанию, которая используется, если ни один не указан. Зависимости компиляции доступны во всех классах проекта. Кроме того, эти зависимости распространяются на зависимые проекты. –

+0

Возможно, мой оригинальный вопрос вызвал путаницу, потому что я использовал «подмодуль». См. Мой отредактированный вопрос выше. –

+0

Да, я больше интересовался областью тестирования. – aperkins

4

Объявляя свою собственную зависимость от xstream и устанавливая область проверки, вы переопределяете зависимости, объявленные mylibrary.

Это на самом деле функция Maven - она ​​позволяет вам делать такие вещи, как зависимость от более поздней версии транзитивной зависимости внутри вашего собственного проекта, а не в конечном итоге упаковывать две разные версии одного и того же артефакта. Например, вы можете зависеть от версии 1.2.15 log4j, но потому, что вы также используете libraryX, который зависит от log4j-1.2.14 - вы не хотите, чтобы и log4j-1.2.15, и log4j-1.2.14 были упакованы в ваш проект.

Если вы действительно хотите, чтобы xstream был упакован в ваш проект, вы не должны объявлять область как test. Фактически, если вы удаляете указанную вами зависимость от xstream, все будет работать так, как вам нравится, так как mylibrary имеет зависимость от компиляции.

+1

В этом случае, если в будущем мне не понадобится использовать mylibrary, или эта библиотека изменяет свою зависимость от xstream на что-то еще, мой проект не сможет пройти тесты. Затем мне нужно будет снова указать xstream для тестовой области проекта. Это функция/ограничение Maven? Я готов принять ограничения Maven, просто пытаясь понять, что такое лучшая практика. –

+0

Я не уверен, что это правильно. Существует более интуитивный механизм исключения нежелательных транзитивных зависимостей, и это блок . – Buhb

+0

«если в будущем мне не понадобится использовать mylibrary, или эта библиотека изменяет зависимость от xstream к чему-то еще, мой проект не сможет пройти тесты». то в этот момент просто добавьте зависимость обратно. Пока вы продолжаете полагаться на ту же версию mylibrary, никаких непредвиденных изменений не должно произойти. Новые версии вашего проекта могут иметь разные потребности - это абсолютно нормально. –

5

Как сказано в ответе mattb, объявляя зависимость как test, область переопределяет транзитивную декларацию зависимости от компиляции, и, как следствие, зависимость не включена в вашу упакованную войну.

Если вам нужна только зависимость в тестах, потому что «mylibrary» нуждается в ее выполнении, вы не должны объявлять зависимость на всех в pom вашего проекта. Пусть процесс разрешения транзитивной зависимости обрабатывает его.

Если ваш проект действительно использует баннер xstream напрямую, вы все равно можете полагаться на транзитивную зависимость, так как вам понадобится совместимая версия для вашего проекта и «mylibrary» для запуска с банком xstream. У вас должны быть модульные тесты, которые выполняют функциональные возможности, и если mylibrary изменяет версию xstream на несовместимую версию, ваши сборки должны завершиться неудачей, и вы можете решить проблему в этот момент.

В целом я бы сказал, что вы должны стараться избегать объявления версий зависимостей непосредственно в многомодульных проектах. Я объявляю версии в разделе dependencyManagement родительского POM, так что ребенку нужно объявить только groupId/artifactId. В качестве альтернативы, от Maven 2.0.9 и далее имеется дополнительная сфера зависимость import:

Эта область используется только на зависимость типа ПОМ в секции. Он указывает, что указанный POM должен быть заменен зависимостями в этом разделе POM. Поскольку они заменяются, зависимости с объемом импорта фактически не участвуют в ограничении транзитивности зависимости.

Таким образом, используя объем импорта вы можете определить общие версии зависимостей в одном POM, импортировать зависимости от того POM в ваш dependencyManagement раздел, и просто объявить GroupID/артефакт в зависимости в вашем другом РОМЕ.

Смежные вопросы