Совместное использование общих ресурсов между проектами maven, не относящимися к JAR

У меня есть несколько проектов Maven, например _1 _, _ 2 _, _ 3_, унаследованных от единственного родителя (назовем его parent), а также являющихся модулями (другого проекта, чем parent, назовем его super).

Все эти проекты имеют pom упаковку. Каждый из этих проектов имеет определенную конфигурацию, но у них есть и общая часть. Чтобы быть более конкретным, каждый проект имеет два файла конфигурации теста JMeter: один специализированный для данного проекта, а другой - общий и идентичный для всех проектов.

Проблема в том, как мне настроить POM, чтобы этот общий файл конфигурации был доступен всем проектам?

Обходной путь - объединить их все в super и использовать профили. Однако в этом случае мне пришлось бы делать отдельную сборку для каждой конфигурации вручную (тогда как теперь я могу просто построить super).

Есть похожие вопросы, например этот, но они связаны с плагином jar , что в данном случае не актуально.

Структура, для справки:

  • Наследование POM:

        parent
          |
    -------------
    |     |     |
    a     b     c
    
  • Файловая структура:

    super
    |
    |-a
    |
    |-b
    |
    |-c
    

person mikołak    schedule 12.07.2012    source источник
comment
Когда вы говорите, что тестовая конфигурация - это конфигурация плагина или отдельные файлы конфигурации для JMeter?   -  person user944849    schedule 12.07.2012
comment
В качестве альтернативы для защиты наследования вы можете создать другой проект с конфигурацией внутри и использовать его в родительском элементе в качестве зависимости с импортом области видимости.   -  person Conan    schedule 12.07.2012
comment
@ user944849: последнее, я сейчас отредактировал вопрос, чтобы было понятнее.   -  person mikołak    schedule 12.07.2012
comment
@Conan: не могли бы вы опубликовать это в качестве ответа и уточнить? Кроме того, я не уверен, повлияет ли это на ваш ответ, но я, вероятно, должен указать, что я использую проект parent для наследования некоторой конфигурации Maven, такой как плагины и свойства.   -  person mikołak    schedule 12.07.2012


Ответы (2)


Я использовал плагин maven-remote-resources для аналогичного цель. Создайте отдельный проект ресурсов (com.company:resourceProj) типа jar. Поместите файлы ресурсов JMeter в /src/main/resources.

/src/main/resources/common.properties  (your filenames obviously)
/src/main/resources/a.properties
etc.

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

Теперь добавьте эту конфигурацию в родительский POM (в профиль тестирования, если хотите):

<properties>
  <shared.resources.dir>${project.build.directory}/shared-resources</shared.resources.dir>
</properties>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-remote-resources-plugin</artifactId>
  <executions>
    <execution>
      <id>load-resources</id>
      <phase>initialize</phase>
      <goals>
        <goal>process</goal>
      </goals>
      <configuration>
        <resourceBundles>
          <resourceBundle>com.company:resourceProj:version</resourceBundle>
        </resourceBundles>
        <attached>false</attached>
        <outputDirectory>${shared.resources.dir}</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

Теперь скажите Maven, что это тестовые ресурсы. Если элементы ваших тестовых ресурсов согласованы между модулями, это также может происходить в родительском элементе, если они разные, то в POM модуля. (По моему опыту с Maven 3 ресурсы, определенные в дочернем проекте, имеют приоритет над родительскими; они не объединяются.)

<testResources>
    <testResource>
      <directory>${shared.resources.dir}</directory>
      <includes>
         <include>common.properties</include>
         <include>${module.file}.properties</include>
      </includes>
    </testResource>
    <!-- any other test resources here -->
  </testResources>

В дочернем модуле определите свойство модуля ресурсов (это модуль a):

<properties>
  <module.file>a</module.file>
</properties>

Адаптируйте это под свой вариант использования.

---- Редактировать ----

Если конфигурация помещается в родительский POM, родительский POM может не построить в зависимости от того, какая конфигурация предоставляется дочерним. Когда мы создаем общие базовые / родительские проекты, мы не хотим требовать, чтобы были определены все свойства, которые должны предоставляться дочерними проектами (наследниками). Поэтому мы активируем этот профиль при создании общих проектов, чтобы обойти все, что относится только к детям.

Для этого добавьте пустой файл pom-packaging.marker в файл basedir родительского проекта. Затем добавьте этот профиль в родительский POM. Когда родительский проект построен, Maven найдет файл маркера, включит профиль и отключит все исполнения, включенные в профиль. Когда создается дочерний проект, файл маркеров не существует, поэтому настройки в основной части POM вступят в силу.

Я использовал эту технику и с плагином Enforcer - родительский элемент определяет правила enforcer, которые должны применяться к проектам, унаследованным от родительского, но не может удовлетворить правила при его сборке. Если плагин предоставляет свойство «пропустить», вы можете включить его в этом профиле вместо использования phase = none в конфигурации плагина.

<profile>
    <id>pom-packaging</id>
    <activation>
        <file>
            <exists>pom-packaging.marker</exists>
        </file>
    </activation>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-remote-resources-plugin</artifactId>
                <executions>
                    <execution>
                            <id>load-resources</id>
                            <phase>none</phase>    <!-- disables this execution -->
                        </execution>
                    </executions>
                </plugin>
          ....  other plugin executions here ....
         </plugins>
    </build>
</profile>
person user944849    schedule 13.07.2012
comment
Это в основном вынуждает вас использовать тип артефакта jar, верно? - person mikołak; 16.07.2012
comment
Jar - это тип проекта общих ресурсов (отдельный проект, который вы создаете), потому что это то, что строит плагин remote-resource. Модули, использующие проект общих ресурсов, могут быть любого типа. Я использовал этот шаблон для включения общих ресурсов для проектов с типом pom раньше. Предложите попробовать, запустите mvn с -X, используя разные фазы в строке cmd, и посмотрите на целевую папку, чтобы увидеть результат. - person user944849; 16.07.2012
comment
Вы правы, это не такая уж большая проблема, поскольку jar должен быть только проект ресурсов. Я попробую еще раз. - person mikołak; 17.07.2012
comment
Я попытался применить это решение, но получил сообщение об ошибке: Не удалось выполнить цель org.apache.maven.plugins: maven-remote-resources-plugin: 1.5: process (load-resources) в проекте Родитель: Архив ресурсов не может быть найден. Это выглядит правильно, так как maven сначала пытается построить родительский pom, т.е. проект общих ресурсов должен быть рядом с текущим родительским элементом, а не под ним, чтобы его можно было построить раньше родительского, верно? - person jan; 04.07.2014
comment
Я добавил больше к этому ответу, чтобы рассказать, как я раньше работал над проблемой @jan. - person user944849; 07.07.2014
comment
@ user944849 Понял. Немного сложно, но очень умно. Я просто добавил еще одну иерархию модулей pom. Это проще в данной конкретной ситуации, но если у вас есть более общие ресурсы, ваше решение, на мой взгляд, будет более элегантным. - person jan; 09.07.2014

Идея с import зависимостями области видимости состоит в том, что вы можете поместить общие ресурсы в отдельный проект, который затем импортируется рядом других; Я думал, что вы могли бы таким образом включить свой общий файл конфигурации.

Вы создаете новый проект с упаковкой pom (может быть, на том же уровне, что и родительский?), А затем включаете его в родительский раздел dependencyManagement с областью действия import. Затем каждый из ваших дочерних проектов может получить его по наследству. Может показаться излишним делать весь проект для одного файла, но у меня не было бы с этим проблем.

Я на самом деле не пробовал это с деревом проектов, упакованных pom, так что вам, возможно, придется немного поиграться, но подход, который я считаю правильным. Здесь есть (очень обширный) пример:

Импорт зависимостей

person Conan    schedule 13.07.2012
comment
Не нужно извиняться :). Однако я не уверен, что область import должна позволять ссылаться на файлы внутри проекта, страница, на которую вы ссылаетесь, указывает, что это только для управления зависимостями, цитата: проекты могут импортировать управляемые зависимости из других проектов. Это достигается путем объявления артефакта pom как зависимости с областью импорта. - person mikołak; 16.07.2012
comment
Ах, понятно, да, ты прав. Я предполагаю, что вам придется упаковать общие ресурсы в новый артефакт, и в этом случае вы можете просто зависеть от этого. Раньше я считал довольно удобным иметь общий тестовый код в отдельной библиотеке, и я не вижу причин, по которым вы не можете упаковать общую конфигурацию таким же образом. - person Conan; 17.07.2012
comment
Верно, и я не вижу проблем с созданием отдельного проекта (это то, что я обычно делаю с общим кодом), однако здесь требуется возможность повторно использовать общие ресурсы, не связанные с кодом, в не-jar проект. - person mikołak; 17.07.2012
comment
Да, без доступа к удобному пути к классам Java упаковка этих ресурсов в банку или что-то подобное не очень хороша, потому что вам придется потом распаковать банку, чтобы прочитать их. Вы можете просто установить общий файл конфигурации JMeter в Maven напрямую, используя mvn install:install-file -Dfile=<shared.jmeter.properties> -DartifactId=shared.jmeter.properties -DgroupId=<your.groupId> -Dversion=1.0 -Dpackaging=properties, а затем добавить его в качестве зависимости. Это нормально для одного файла, но не поможет, если у вас будет несколько общих файлов, так что это не полное решение. Стоит попробовать? - person Conan; 17.07.2012