Возможность получения pom-агрегатора Maven для ввода свойств в pom-модули (без использования наследования) - PullRequest
4 голосов
/ 30 марта 2011

Небольшой вопрос о целесообразности для вас Maven. В частности, о том, можем ли мы определить свойства в агрегирующем pom, а затем внедрить их в ссылочные модули, что позволит этому модулю локально перезаписать свойства по умолчанию, определенные в иерархии наследования.

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

Итак, наша установка; Я сведу это к основам. У нас есть два исходных проекта, A и B. Каждый из них на самом деле является дочерним модулем другого, ParentA и ParentB соответственно. ParentA и ParentB технически имеют несколько дочерних модулей, но в этом примере для простоты я буду только явно ссылаться на каждый из них. Все идет нормально. ParentA ссылается на A как на подмодуль, а A ссылается на ParentA в качестве его родителя. Те же отношения применяются между B и ParentB.

Теперь самое интересное. Мы бы хотели, чтобы родительский pom для ParentA и ParentB наследовал общие свойства и конфигурацию, такую ​​как dependencyManagement, плагины и т. Д. Но мы не хотим, чтобы этот родительский pom отвечал за сборки. Вместо этого мы хотели бы определить ряд сборочных проектов, которые выборочно собирают различные модули. В этом примере я представлю BuildAB и BuildB. Первая строит A, а затем B, тогда как вторая строит просто B. В действительности у нас есть довольно много из этих чередующихся групп модулей и зависимостей. Наконец, чтобы завершить картину, мы имеем зависимость от B до A.

Позвольте мне попытаться нарисовать это, используя искусство ascii;)

Наследование

A --> ParentA --> parent
B --> ParentB --> parent

Подмодульные отношения

BuildAB ==> { (ParentA ==> A) (ParentB ==> B) }
BuildB ==> (ParentB ==> B)

1017 * Зависимость *

B > A

Теперь, в существующем состоянии, невозможно использовать свойства из файлов BuildAB и BuildB для определения зависимостей; эти файлы сборки не являются частью какого-либо дерева наследования, поэтому ничто не подберет свойства. Но мы действительно хотим по-разному управлять версиями зависимостей при запуске BuildAB и BuildB; простое помещение зависимостей в супер-родитель не приведет к сокращению наших требований.

Если вам интересно, почему это может быть связано с тем, что одна группа может разрабатывать модули B и, возможно, вносить незначительные изменения в A. Другие разработчики могут работать над последним и лучшим проектом А, который имеет последствия для B благодаря зависимости. У нас есть отличные механизмы для обработки этого в исходном коде благодаря Mercurial. Но мы действительно изо всех сил пытаемся сделать это с Maven.

В идеале, каждый файл Build должен в первую очередь полагаться на субмодули, наследуемые от Parent. Но когда нам нужно переопределить это наследование, мы хотели бы иметь возможность указать инъецируемые свойства в файле сборки, которые будут действовать точно так, как если бы они были указаны в модуле изначально. Конечно, все без фактического изменения pom, который контролируется источником.

Мы хотели бы оценить, есть ли возможность изменить maven для этого с помощью плагина или патча.

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

Итак, в основном,

  • Вы когда-нибудь сталкивались с подобными требованиями и работали ли они с существующими плагинами?
  • Есть ли простой трюк, который мы пропустили?
  • Вы написали похожий плагин и можете порекомендовать место для запуска?
  • Вам известна какая-либо практическая причина, по которой такой плагин может не работать?
  • Работаете ли вы над исходным кодом maven и знаете, сможем ли мы предоставить какой-либо результирующий код ... и где мы должны начать искать, если захотим.

Последний комментарий. Мы разрабатываем в Eclipse, поэтому нам также нужно, чтобы сборка работала без внедрения свойств. Я ожидаю, что это будет через обычное дерево наследования.

Большое спасибо всем, я знаю, что это немного сложный вопрос.

1 Ответ

2 голосов
/ 08 мая 2013

Для всех видов специальной магии: используйте расширение maven build .

Это не очень хорошо известно (и, как обычно, для maven, вздох), нехорошо документированный механизм, но, насколько я вижу, это действительно официально одобренный способ влиять на процесс сборки в целом.

import org.apache.maven.AbstractMavenLifecycleParticipant;
import org.apache.maven.execution.MavenSession;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;

@Component(role = AbstractMavenLifecycleParticipant.class, hint = "mySpecialService")
public class MySpecialExtension
    extends AbstractMavenLifecycleParticipant
{

    @Requirement
    private Logger logger;

    @Override
    public void afterProjectsRead( MavenSession session ) {
        // ...do you magic here

        // for example, to set some POM properties
        Properties sysProps = session.getSystemProperties();
        ....
        Properties projProps = session.getCurrentProject().getProperties();
        projProps.setProperty("..",val);

Эта функция вызывается сразу после синтаксического анализа файлов pom.xml исоздание основного POM в памяти, но до начала каких-либо действий по сборкеВ многомодульном проекте расширение вызывается из корневого проекта, даже если оно определено только в некотором подмодуле.На данный момент теоретически вы можете сделать что-нибудь со своим процессом сборки, например, просто вставить некоторые свойства в pom, загрузить дополнительные проекты из менеджера артефактов и добавить их в реактор сборки, посмотреть некоторые специальные плагины, изменить POMкакой-то модуль или даже сборка вещей, которые нигде не объявлены (!)

Чтобы создать такое расширение, вы помещаете свой код в отдельный проект maven

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <prerequisites>
        <maven>3.0</maven>
    </prerequisites>

    <name>my-special-service</name>
    <groupId>my.group</groupId>
    <artifactId>my-special-service</artifactId>
    <packaging>jar</packaging>

    <parent>
       ....
    </parent>

    <properties>
        <mavenApiVer>3.0.5</mavenApiVer>
        <mavenModelVer>2.2.1</mavenModelVer>
    </properties>

<build>
    <plugins>
        <!-- Maven Build Extension -->
        <plugin>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-component-metadata</artifactId>
            <version>1.5.5</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate-metadata</goal>
                        <!-- goal>generate-test-metadata</goal -->
                    </goals>
                </execution>
            </executions>
            </plugin>
            <!-- Maven Build Extension -->
        </plugins>
    </build>


    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-project</artifactId>
            <version>${mavenModelVer}</version>
        </dependency>

        <!-- Maven Build Extension -->
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-compat</artifactId>
            <version>${mavenApiVer}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-core</artifactId>
            <version>${mavenApiVer}</version>
        </dependency>
        <!-- Maven Build Extension -->

        ....

    </dependencies>
</project>

Чтобы использовать вашрасширение в каком-то другом проекте, просто добавьте следующее

<build>
    <extensions>
        <extension><!-- Maven Build Extension: my Special Service -->
            <groupId>my.group</groupId>
            <artifactId>my-special-service</artifactId>
            <version>.....</version>
        </extension>
    </extensions>

    <pluginManagement>
    ....

В нашем конкретном случае использования у нас было несколько общих сервисов (особенно URL-адреса баз данных, используемые из конкретных плагинов в процессе сборки)который мы должны получить из системы управления конфигурациями прозрачно.Развертывание файлов свойств каждому разработчику и каждому серверу сборки нецелесообразно, поскольку среда очень разнородна.

...