Maven2 свойство, которое указывает родительский каталог - PullRequest
95 голосов
/ 18 июня 2009

У меня есть многомодульный проект, подобный этому:

main-project/
    module1/
    module2/
        sub-module1/
        sub-module2/
        sub-module3/
        ...
    module3/
    module4/
    ...

Мне нужно определить набор свойств (которые зависят от среды, в которой я хочу выпустить свой проект) в Maven2. Я не буду использовать <properties>, так как есть много свойств ... Таким образом, я использую плагин Properties Maven2 .

Файлы свойств находятся в каталоге main-project/. Как я могу установить правильный каталог в основном файле pom.xml, чтобы указать дочерним элементам, где искать файл свойств?

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>properties-maven-plugin</artifactId>
    <version>1.0-alpha-1</version>
    <executions>
        <execution>
            <phase>initialize</phase>
            <goals>
                <goal>read-project-properties</goal>
            </goals>
            <configuration>
                <files>
                    <file>???/env_${env}.properties</file>
                </files>
            </configuration>
        </execution>
    </executions>
</plugin>

Если я установлю только <file>env_${env}.properties</file>, то, когда Maven2 скомпилирует первый модуль, он не найдет файл main-project/env_dev.properties. Если я установлю <file>../env_${env}.properties</file>, то будет возникать ошибка на родительском уровне или на любом уровне субмодуля ...

Ответы [ 18 ]

2 голосов
/ 17 сентября 2009
<plugins>
  <plugin>
    <groupId>org.codehaus.groovy.maven</groupId>
    <artifactId>gmaven-plugin</artifactId>
    <version>1.0</version>
    <executions>
      <execution>
        <phase>validate</phase>
        <goals>
          <goal>execute</goal>
        </goals>
        <configuration>
          <source>
            import java.io.File
            project.properties.parentdir = "${pom.basedir}"
            while (new File(new File(project.properties.parentdir).parent, 'pom.xml').exists()) {
                project.properties.parentdir = new File(project.properties.parentdir).parent
            }
          </source>
        </configuration>
      </execution>
    </executions>
  </plugin>
  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>properties-maven-plugin</artifactId>
    <version>1.0-alpha-2</version>
    <executions>
      <execution>
        <phase>initialize</phase>
        <goals>
          <goal>read-project-properties</goal>
        </goals>
        <configuration>
          <files>
            <file>${parentdir}/build.properties</file>
          </files>
        </configuration>
      </execution>
    </executions>
  </plugin>
  ...
1 голос
/ 29 августа 2009

В ответе на другой вопрос я показал, как плагин maven-properties-properties может быть расширен для использования дескрипторов внешних свойств, определенных в зависимостях Maven.

Вы можете расширить эту идею, чтобы иметь несколько jar дескрипторов, каждый с именем среды в составе artifactId, содержащий $ {env} .properties. Затем вы можете использовать свойство, чтобы выбрать соответствующий файл jar и свойства, например:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>properties-ext-maven-plugin</artifactId>
  <version>0.0.1</version>
  <executions>
    <execution>
      <id>read-properties</id>
      <phase>initialize</phase>
      <goals>
        <goal>read-project-properties</goal>
      </goals>
    </execution>
  </executions>                              
  <configuration>
    <filePaths>
      <!--assume the descriptor project has a file in the root of the jar -->
      <filePath>${env}.properties</filePath>
    </filePaths>
  </configuration> 
  <dependencies>
    <!-- reference the properties jar for the particular environment-->
    <dependency>
      <groupId>some.descriptor.group</groupId>
      <artifactId>env-${env}-descriptor</artifactId>
      <version>0.0.1</version>
    </dependency>
  </dependencies>
</plugin>
1 голос
/ 15 апреля 2016

Я получил доступ к каталогу выше, используя $ {basedir} .. \ src \

1 голос
/ 28 декабря 2011

Я просто улучшаю скрипт groovy, описанный выше, чтобы записать свойство в корневой родительский файл свойств:

import java.io.*;
String p = project.properties['env-properties-file']
File f = new File(p)
if (f.exists()) {
try{
FileWriter fstream = new FileWriter(f.getAbsolutePath())
BufferedWriter out = new BufferedWriter(fstream)
String propToSet = f.getAbsolutePath().substring(0, f.getAbsolutePath().lastIndexOf(File.separator))
if (File.separator != "/") {
propToSet = propToSet.replace(File.separator,File.separator+File.separator+File.separator)
}
out.write("jacoco.agent = " + propToSet + "/lib/jacocoagent.jar")
out.close()
}catch (Exception e){
}
}
String ret = "../"
while (!f.exists()) {
f = new File(ret + p)
ret+= "../"
}
project.properties['env-properties-file-by-groovy'] = f.getAbsolutePath()
0 голосов
/ 18 июня 2009

Вы пробовали ../../env_${env}.properties?

Обычно мы делаем следующее, когда module2 находится на том же уровне, что и подмодули

<modules>
    <module>../sub-module1</module>
    <module>../sub-module2</module>
    <module>../sub-module3</module>
</modules>

Я думаю, что ../.позволил бы вам подскочить на два уровня.Если нет, вы можете связаться с авторами плагина и узнать, является ли это известной проблемой.

0 голосов
/ 13 октября 2015

Мне нужно было решить аналогичную проблему для локального репозитория, размещенного в основном проекте многомодульного проекта. По сути, реальный путь был ${basedir} / lib. Наконец я остановился на этом в своем parent.pom:

<repository>
    <id>local-maven-repo</id>
    <url>file:///${basedir}/${project.parent.relativePath}/lib</url>
</repository>

То, что basedir всегда показывает текущему локальному модулю, нет способа получить путь к «главному» проекту (позор Maven). Некоторые из моих подмодулей глубже на один, некоторые глубже на два, но все они являются прямыми подмодулями родителя, который определяет URL репо.

Так что это не решает проблему в целом. Вы всегда можете объединить его с принятым ответом Клэя и определить какое-то другое свойство - работает нормально и должно быть переопределено только для случаев, когда значение из parent.pom недостаточно хорошо. Или вы можете просто перенастроить плагин - что вы делаете только в POM-артефактах (родителях других подмодулей). Значение, извлеченное в свойство, вероятно, будет лучше, если оно понадобится вам в других местах, особенно когда ничего в конфигурации плагина не меняется.

Использование basedir в значении было здесь важной частью, потому что URL file://${project.parent.relativePath}/lib не хотел делать трюк (я удалил одну косую черту, чтобы сделать ее относительной). Использовать свойство, которое дает мне хороший абсолютный путь, а затем идти относительно него, было необходимо.

Когда путь не является URL / URI, вероятно, это не такая проблема, чтобы отбрасывать basedir.

0 голосов
/ 08 сентября 2015

Это расширяет ответ romaintaz, который удивителен тем, что решает проблему, а также ясно указывает на недостающую функциональность maven. Я взял более позднюю версию плагина и добавил случай, когда проект может иметь глубину более 3-х уровней.

<pluginManagement>
  <plugins>
    ..
    <plugin>
      <groupId>org.codehaus.gmaven</groupId>
      <artifactId>groovy-maven-plugin</artifactId>
      <version>2.0</version>
    </plugin>
    ..
  </plugins>
</pluginManagement>

Я решил не использовать свойство для определения имени файла. Обратите внимание, что если build.properties не найден, он будет вращаться вечно. Я добавил обнаружение .git dir, но не хотел слишком усложнять ответ, поэтому здесь он не отображается.

  <plugin>
      <groupId>org.codehaus.gmaven</groupId>
      <artifactId>groovy-maven-plugin</artifactId>
      <executions>
          <execution>
              <phase>validate</phase>
              <goals>
                  <goal>execute</goal>
              </goals>
              <configuration>
                 <source>
                    import java.io.File;
                    String p = "build.properties";
                    while(true) {
                      File f = new File(p); 
                      if(f.exists()) {
                        project.properties['project-properties-file'] = f.getAbsolutePath();
                        break;
                      }
                      else {
                        p = "../${p}";
                      }
                    }
                </source>
              </configuration>
          </execution>
      </executions>
  </plugin>
0 голосов
/ 19 сентября 2009

Я думаю, что если вы используете шаблон расширения, используемый в примере для плагина и мультимодуля findbugs, вы сможете установить глобальные свойства, связанные с абсолютными путями. Он использует топ

пример для нескольких модулей

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

Проблема в том, что для выполнения этой работы необходимо добавить новый верхний уровень в многомодульный проект. Я попытался отойти от действительно несвязанного проекта build-config, но он был грязным и казался хрупким.

...