Нахождение корневого каталога проекта многомодульного реактора Maven - PullRequest
61 голосов
/ 21 июня 2010

Я хочу использовать плагин maven-dependency-plugin для копирования EAR-файлов из всех подмодулей моего многомодульного проекта в каталог, который находится относительно корневого каталога всего проекта.

То есть мой макет выглядит примерно так, имена изменены:

to-deploy/
my-project/
    ear-module-a/
    ear-module-b/
    more-modules-1/
        ear-module-c/
        ear-module-d/
    more-modules-2/
        ear-module-e/
        ear-module-f/
    ...

И я хочу, чтобы все EAR-файлы были скопированы из целевых каталогов их соответствующих модулей в my-project/../to-deploy, поэтому я в итогес

to-deploy/
    ear-module-a.ear
    ear-module-b.ear
    ear-module-c.ear
    ear-module-d.ear
    ear-module-e.ear
    ear-module-f.ear
my-project/
    ...

Я мог бы сделать это с относительным путем в каждом ушном модуле, например так:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>install</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>${project.groupId}</groupId>
                                <artifactId>${project.artifactId}</artifactId>
                                <version>${project.version}</version>
                                <type>ear</type>
                                <outputDirectory>../../to-deploy</outputDirectory>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Но я бы не хотел указывать относительный путь в <outputDirectory> элемент.Я бы предпочел что-то вроде ${reactor.root.directory}/../to-deploy, но я не могу найти ничего подобного.

Кроме того, я бы предпочел, если бы был какой-то способ унаследовать эту конфигурацию подключаемого модуля maven-зависимостей, поэтому яя должен указать его для каждого EAR-модуля.

Я также пытался унаследовать пользовательское свойство от корневого модуля:

<properties>
    <myproject.root>${basedir}</myproject.root>
</properties>

Но когда я пытался использовать ${myproject.root} в ухе-модуль POM, ${basedir} будет преобразован в базовый модуль ear-модуля.

Кроме того, я нашел http://labs.consol.de/lang/de/blog/maven/project-root-path-in-a-maven-multi-module-project/, где предлагается, чтобы каждый разработчик и, предположительно, сервер непрерывной интеграции должны были настроитькорневой каталог в файле profiles.xml, но я не считаю это решением.

Так есть ли простой способ найти корень многомодульного проекта?

Ответы [ 10 ]

68 голосов
/ 06 октября 2011

use ${session.executionRootDirectory}

Для записи, ${session.executionRootDirectory} работает для меня в файлах pom в Maven 3.0.3.Это свойство будет каталогом, в котором вы работаете, поэтому запустите родительский проект, и каждый модуль может получить путь к этому корневому каталогу.

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

ДляНапример,

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-artifact</id>
            <phase>package</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>${project.artifactId}</artifactId>
                        <version>${project.version}</version>
                        <type>${project.packaging}</type>
                    </artifactItem>
                </artifactItems>
                <outputDirectory>${session.executionRootDirectory}/target/</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>
22 голосов
/ 28 марта 2018

Начиная с Maven 3.3.1, вы можете использовать ${maven.multiModuleProjectDirectory} для этой цели.(спасибо https://stackoverflow.com/a/48879554/302789)

edit: похоже, это работает правильно только когда у вас есть папка .mvn в корне вашего проекта.

20 голосов
/ 13 января 2012

То, что я использовал в своих проектах, - это переопределение свойства в poms подмодуля.

<code>    root:           <myproject.root>${basedir}</myproject.root>
    moduleA:        <myproject.root>${basedir}/..</myproject.root>
    other/moduleX:  <myproject.root>${basedir}/../..</myproject.root>

Таким образом, у вас все еще есть относительные пути,но вы можете определить плагин один раз в корневом модуле, и ваши модули унаследуют его с правильной заменой myproject.root.

16 голосов
/ 28 ноября 2013

Существует плагин maven, который решает эту конкретную проблему: directory-maven-plugin

Он назначит корневой путь вашего проекта для свойства по вашему выбору. См. highest-basedir цель в документах.

Например:

<!-- Directory plugin to find parent root directory absolute path -->
<plugin>
  <groupId>org.commonjava.maven.plugins</groupId>
  <artifactId>directory-maven-plugin</artifactId>
  <version>0.1</version>
  <executions>
    <execution>
      <id>directories</id>
      <goals>
        <goal>highest-basedir</goal>
      </goals>
      <phase>initialize</phase>
      <configuration>
        <property>main.basedir</property>
      </configuration>
    </execution>
  </executions>
</plugin>

Затем используйте ${main.basedir} в любом месте вашего родительского / дочернего pom.xml.

4 голосов
/ 22 июня 2016

Как и предполагали другие, каталог-мавен-плагин это путь. Однако я обнаружил, что он лучше всего работает с целью 'directory-of', как описано здесь: https://stackoverflow.com/a/37965143/6498617.

Я предпочитаю, так как использование самого высокого basedir не работало для меня с многомодульным проектом, с вложенными многомодульными помпами. Директория цели позволяет вам установить свойство для пути к любому модулю во всем проекте, включая, конечно, корень. Это также намного лучше, чем $ {session.executionRootDirectory}, потому что он всегда работает, независимо от того, создаете ли вы корень или субмодуль, и независимо от текущего рабочего каталога, из которого вы используете mvn.

2 голосов
/ 06 июня 2012

Я столкнулся с подобной проблемой, так как мне нужно было копировать файлы между проектами. То, что делает Maven, логично, потому что оно будет держать pom.xml установленным в репозитории от жестко закодированного значения.

Мое решение заключалось в том, чтобы поместить скопированный каталог в артефакт Maven, а затем использовать Ant для извлечения / копирования

1 голос
/ 02 июля 2013

У меня сработал следующий небольшой профиль. Мне нужна была такая конфигурация для CheckStyle, которую я поместил в каталог config в корне проекта, чтобы я мог запустить ее из основного модуля и из подмодулей.

<profile>
    <id>root-dir</id>
    <activation>
        <file>
            <exists>${project.basedir}/../../config/checkstyle.xml</exists>
        </file>
    </activation>
    <properties>
        <project.config.path>${project.basedir}/../config</project.config.path>
    </properties>
</profile>

Он не будет работать для вложенных модулей, но я уверен, что его можно изменить для этого, используя несколько профилей с разными exists. (Я понятия не имею, почему в теге подтверждения должно быть "../ .." и просто ".." в самом переопределенном свойстве, но оно работает только таким образом.)

1 голос
/ 14 декабря 2010

Другое решение - использовать задачу ant для записи «rootdir = $ {basedir}» в target / root.properties в корневом проекте, а затем использовать плагин Properties для чтения этого файла.обратно. Я сам не пробовал, но думаю, это должно сработать ..?

1 голос
/ 21 июня 2010

Мне не известен «хороший» способ найти корень многомодульного проекта.Но вы можете немного улучшить свой текущий подход.

Первой альтернативой было бы создание дополнительного модуля непосредственно под корневым проектом, объявление всех EAR как зависимостей в нем и использование dependency:copy-dependencies для копирования зависимостей модуля вкаталог to-deploy (относительно).Да, путь все равно будет относительным, но поскольку конфигурация подключаемого модуля зависимостей будет централизованной, я не нахожу это раздражающим.

Второй альтернативой будет использование вместо этого Плагина сборки Maven подключаемого модуля Maven Dependency для создания дистрибутива в формате dir (это создаст дистрибутив в каталоге).Это на самом деле то, что я бы сделал.

0 голосов
/ 26 марта 2016

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

<properties>    
<source> import java.io.File; 
        String p =project.properties['env-properties-file']; 
        File f = new File(p); 
        if (!f.exists()) 
        { 
           f = new File("../" + p); 
          if (!f.exists()) 
          { 
             f = new File("../../" + p); 
          } 
        } 
        // setting path together with file name in variable xyz_format 
        project.properties['xyz_format'] =f.getAbsolutePath() 
                            + File.separator 
                            + "abc_format.xml"; 
</source>
</properties>   

, а затем:

  <properties>
     <snapshots>http://localhost:8081/snapshots<snapshots>
     <releases>http://localhost:8081/releases</releases>
     <sonar>jdbc:oracle:thin:sonar/sonar@localhost/XE</sonar>
     <sonar.jdbc.username>sonar</sonar.jdbc.username>
     <format.conf> ${xyz_format}</format.conf>  <---- here is it!
    </properties>

это работает!

...