2016-03-04 4 views
1

У меня есть 3 банки, а именно jar1, jar2, jar3.Класс Путь и профиль maven

В jar1 есть код, который считывает файл из пути к классам. Однако файл не будет присутствовать в classpath jar1. Вместо этого jar2 будет подключен, поскольку зависимость jar1 и jar2 classpath будет содержать этот файл.

У меня есть jar3, который также будет содержать тот же файл в своем пути к классам, но я бы объявил область как test для jar3 в pom.xml jar1.

Теперь, когда тестовые примеры выполняются, как мы можем сказать maven, чтобы всегда брать файл из jar3 (scope as test) classpath, хотя jar2 задан как основная зависимость (область не как тест)?

Возможно ли это через профили maven? Если да, то как мы можем это указать? Или мы можем использовать maven-resources-plugin для копирования файла во время проверки?

Как именно будет устанавливаться classpath, если одни и те же файлы присутствуют в нескольких баночках, заданных как зависимость?

Образец jar1 pom.xml

<dependencies> 
     <dependency> 
      <groupId>com.test</groupId> 
      <artifactId>jar2</artifactId> 
      <version>0.1-SNAPSHOT</version> 
     </dependency> 
     <dependency> 
      <groupId>com.test</groupId> 
      <artifactId>jar3</artifactId> 
      <version>0.1-SNAPSHOT</version> 
      <scope>test</scope> 
     </dependency> 
</dependencies> 

Оба jar2 и jar3 имеет файл ресурсов.

Вопрос: Что будет выбрано и почему?

ответ

1

Если вы зависимостями находятся на том же уровне в дереве зависимостей, порядок декларирования в вашем ПОМ выиграет, согласно Maven Dependency Mediation документ:

Обратите внимание, что если две версии зависимостей находятся на одной и той же глубине дерево зависимостей, пока Maven не 2.0.8 он не был определен, который можно было бы выиграть, но с Maven 2.0.9 это порядок в декларации, что имеет значение: первое объявление выигрывает

Так что в вашем случае две зависимости находятся на одном уровне в дереве зависимостей (первый уровень, объявленный в POM) и compile scope будет присутствовать всякий раз, когда test будет областью видимости, так как jar2 победит, потому что вы объявили его первым в своем POM (в соответствии с отключенным вами сообщением).

Если вы хотите, чтобы файл загружался всегда с jar3, но только во время тестов просто объявите jar3 первым в ваших зависимостях. Это не повлияет на конечный результат (находящийся в области test), но он определит порядок для пути к классу для тестирования и как таковой даст вам ожидаемый сценарий. Для этого вам не нужны профили Maven.


простой тест, чтобы проверить это:

Давайте определим свойство file.properties в src\main\resources проекта Maven.Файл будет выглядеть следующим образом для проекта resource-provider (артефакт):

property=from-resource-provider 

А следующие для проекта resource-provider2 (артефакт):

property=from-resource-provider2 

Примечания: то же самое имя файла в двух различных проекты с различным содержание.

Тогда в проекте потребителя (resource-consumer) мы могли бы иметь следующий тест JUnit образец случай:

public class MainTest { 

    @Test 
    public void checkClassPath() { 
     InputStream is = MainTest.class.getResourceAsStream("/file.properties"); 
     Scanner s = new Scanner(is); 
     System.out.println(s.nextLine()); 
    } 

} 

Для следующих зависимостей в resource-consumer:

<dependencies> 
    <dependency> 
     <groupId>com.sample</groupId> 
     <artifactId>resource-provider2</artifactId> 
     <version>0.0.1-SNAPSHOT</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>com.sample</groupId> 
     <artifactId>resource-provider</artifactId> 
     <version>0.0.1-SNAPSHOT</version> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.11</version> 
     <scope>test</scope> 
    </dependency> 
</dependencies> 

Выход выполнения теста будет:

------------------------------------------------------- 
T E S T S 
------------------------------------------------------- 
Running com.sample.MainTest 
property=from-resource-provider2 
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.051 sec 

Итак, первый de объявленная пенсия, resource-provider2, выиграна (отметьте область, test).

Изменение порядка зависимостей, чтобы:

<dependencies> 
    <dependency> 
     <groupId>com.sample</groupId> 
     <artifactId>resource-provider</artifactId> 
     <version>0.0.1-SNAPSHOT</version> 
    </dependency> 
    <dependency> 
     <groupId>com.sample</groupId> 
     <artifactId>resource-provider2</artifactId> 
     <version>0.0.1-SNAPSHOT</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.11</version> 
     <scope>test</scope> 
    </dependency> 
</dependencies> 

бы вместо того, чтобы дать следующий вывод:

------------------------------------------------------- 
T E S T S 
------------------------------------------------------- 
Running com.sample.MainTest 
property=from-resource-provider 
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.07 sec 

Примечание: на этот раз resource-provider выиграна, потому что он был объявлен первым и потому, что compile сфера также является частью от test scope, а наоборот - неверно.

+0

.. Благодарю вас. Очень ясный информация .. –

+0

@svsteja добро пожаловать. Боковое замечание: при использовании такого подхода (на основе заказа) я бы рекомендовал добавлять комментарии к вашему pom, чтобы помочь в обслуживании и устранении неполадок другим разработчикам или будущему самостоятельно :) –