Собственность Maven2, что указывает на родительский каталог
у меня есть проект с несколькими модулями, как этот:
main-project/
module1/
module2/
sub-module1/
sub-module2/
sub-module3/
...
module3/
module4/
...
мне нужно определить набор свойств (которые зависят от среды, в которой я хочу выпустить свой проект) в Maven2.
Я не буду использовать <properties> как есть много свойств...
Таким образом, я использую свойства плагин Maven2.
файлы свойств находятся в .
Как я могу установить правильный каталог в главном пом.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 компилирует первый модуль, он не найдет . Если я установил <file>../env_${env}.properties</file>, то ошибка будет поднята на родительском уровне, или на любом уровне подмодуля...
18 ответов:
попробуйте установить свойство в каждом pom, чтобы найти основной каталог проекта.
в Родительском:
<properties> <main.basedir>${project.basedir}</main.basedir> </properties>дети:
<properties> <main.basedir>${project.parent.basedir}</main.basedir> </properties>во внуках:
<properties> <main.basedir>${project.parent.parent.basedir}</main.basedir> </properties>
Я нашел решение для решения моей проблемы:я ищу файлы свойств с помощью плагина Groovy Maven.
поскольку мой файл свойств обязательно находится в текущем каталоге, in .. или внутрь ../.., Я написал небольшой Заводной код, который проверяет эти три папки.
вот выдержка из моего пом.XML-код:
<!-- Use Groovy to search the location of the properties file. --> <plugin> <groupId>org.codehaus.groovy.maven</groupId> <artifactId>gmaven-plugin</artifactId> <version>1.0-rc-5</version> <executions> <execution> <phase>validate</phase> <goals> <goal>execute</goal> </goals> <configuration> <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); } } project.properties['env-properties-file-by-groovy'] = f.getAbsolutePath(); </source> </configuration> </execution> </executions> </plugin> <!-- Now, I can load the properties file using the new 'env-properties-file-by-groovy' property. --> <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-properties-file-by-groovy}</file> </files> </configuration> </execution> </executions> </plugin>это работает, но мне не очень нравится.
Итак, если у вас есть лучшее решение, не стесняйтесь пишите!
Итак, проблема, как я вижу, заключается в том, что вы не можете получить абсолютный путь к родительскому каталогу в maven.
Я слышал, что это говорили как анти-шаблон, но для каждого анти-шаблона есть реальный, законный случай использования для него, и я устал от maven, говорящего мне, что я могу только следовать их шаблонам. так что работа вокруг я нашел, чтобы использовать antrun. Попробуйте это в детском пом.XML-код:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.7</version> <executions> <execution> <id>getMainBaseDir</id> <phase>validate</phase> <goals> <goal>run</goal> </goals> <configuration> <exportAntProperties>true</exportAntProperties> <target> <!--Adjust the location below to your directory structure --> <property name="main.basedir" location="./.." /> <echo message="main.basedir=${main.basedir}"/> </target> </configuration> </execution> </executions> </plugin>если вы запустите
mvn verifyвы должны увидеть что-то вроде этого:main: [echo] main.basedir=C:\src\parent.project.dir.nameвы можете использовать
${main.basedir}в любой из других плагинов и т. д. Мне потребовалось время, чтобы понять это, поэтому надеюсь, что это поможет кому-то еще.
использовать каталог-maven-плагин с каталогом-цели.
в отличие от других предложений:
- это решение работает для многомодульных проектов.
- он работает независимо от того, строите ли вы весь проект или подмодуль.
- он работает независимо от того, запускаете ли вы maven из корневой папки или подмодуля.
- нет необходимости устанавливать относительное свойство пути в каждом подмодуле!
плагин позволяет установите для выбранного свойства абсолютный путь любого из модулей проекта. В моем случае я установил его в корневой модуль... В моем проекте root pom:
<plugin> <groupId>org.commonjava.maven.plugins</groupId> <artifactId>directory-maven-plugin</artifactId> <version>0.1</version> <executions> <execution> <id>directories</id> <goals> <goal>directory-of</goal> </goals> <phase>initialize</phase> <configuration> <property>myproject.basedir</property> <project> <groupId>com.my.domain</groupId> <artifactId>my-root-artifact</artifactId> </project> </configuration> </execution> </executions> </plugin>С этого момента, ${myproject.basedir} в любом субмодуле pom всегда имеет путь к корневому модулю проекта. И, конечно же, вы можете установить свойство для любого модуля, а не только корень...
в моем случае это работает так:
... <properties> <main_dir>${project.parent.relativePath}/..</main_dir> </properties> ... <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>${main_dir}/maven_custom.properties</file> </files> </configuration> </execution> </executions> </plugin>
следующий небольшой профиль работал для меня. Мне нужна была такая конфигурация для 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' s. (Я понятия не имею, почему там должно быть "../.."в теге проверки и просто".."в самом переопределенном свойстве, но это работает только таким образом.)
другой вариант:
в Родительском pom используйте:
<properties> <rootDir>${session.executionRootDirectory}</rootDir> <properties>в дочерних poms вы можете ссылаться на эту переменную.
главное предостережение: это заставляет вас всегда выполнять команду из основного родительского каталога pom. Затем, если вы хотите запускать команды (например, тест) только для определенного модуля, используйте следующий синтаксис:
mvn test --projects
конфигурация surefire для параметизации переменной "path_to_test_data" может тогда быть:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>${surefire.plugin.version}</version> <configuration> <systemPropertyVariables> <path_to_test_data>${rootDir/../testdata}</path_to_test_data> </systemPropertyVariables> </configuration> </plugin>
Я нашел решение для решения этой проблемы: используйте ${родителя.relativePath}
<parent> <artifactId>xxx</artifactId> <groupId>xxx</groupId> <version>1.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> <build> <filters> <filter>${parent.relativePath}/src/main/filters/filter-${env}.properties</filter> </filters> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build>
вы находитесь в проекте C, проект C является подмодулем B и B является подмодулем A. вы пытаетесь достичь модуля D
src/test/config/etcкаталог из проекта C. D также является подмодулем A. следующее выражение позволяет получить путь URI:-Dparameter=file:/${basedir}/../../D/src/test/config/etc
<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> ...
на ответ на другой вопрос Я показал, как плагин maven-properties-plugin может быть расширен для использования внешних дескрипторов свойств, определенных в зависимостях Maven.
вы можете расширить эту идею, чтобы иметь несколько дескрипторов jars, каждый с именем среды как часть artifactId, содержащий ${env}.свойства. Затем вы можете использовать свойство для выбора соответствующего файла 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>
Я просто улучшаю скрипт 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()
ты
../../env_${env}.properties?обычно мы делаем следующее, Когда module2 находится на том же уровне, что и подмодули
<modules> <module>../sub-module1</module> <module>../sub-module2</module> <module>../sub-module3</module> </modules>Я думаю ../.. позволит вам прыгать на два уровня вверх. Если нет, вы можете связаться с авторами плагина и посмотреть, является ли это известной проблемой.
Я думаю, что если вы используете шаблон расширения, используемый в примере для FindBugs plugin & multimodule, вы можете установить глобальные свойства, связанные с абсолютными путями. Он использует
POM верхнего уровня имеет несвязанный проект build-config и приложение-родитель для модулей многомодульного проекта. Приложение-родитель использует расширение, чтобы связать себя с проектом build-config и получить от него ресурсы. Это используется для переноса общих конфигурационных файлов в модули. Это может быть канал для свойств, а также. Вы можете записать верхний каталог в файл свойств, используемый build-config. (это кажется слишком сложным)
проблема в том, что новый верхний уровень должен быть добавлен в многомодульный проект, чтобы сделать эту работу. Я попытался сделать шаг в сторону с действительно несвязанным проектом build-config, но он был kludgy и казался хрупким.
Это расширяет ответ romaintaz, который является удивительным в том, что решает проблему, а также четко указывает на отсутствующую функциональность maven. Я взял более позднюю версию плагина и добавил случай, когда проект может быть более 3 уровней глубиной.
<pluginManagement> <plugins> .. <plugin> <groupId>org.codehaus.gmaven</groupId> <artifactId>groovy-maven-plugin</artifactId> <version>2.0</version> </plugin> .. </plugins> </pluginManagement>Я решил не использовать свойство для определения имени файла. Обратите внимание, если сборка.свойства не найдены это будет вращаться вечно. Я добавил .обнаружение 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>
мне нужно было решить аналогичную проблему для локального репозитория, размещенного в основном проекте многомодульного проекта. По сути реальный путь был
${basedir}/ lib. Наконец я остановился на этом в своемparent.pom:<repository> <id>local-maven-repo</id> <url>file:///${basedir}/${project.parent.relativePath}/lib</url> </repository>это
basedirвсегда показывает текущий локальный модуль, нет способа получить путь к проекту "master" (стыд Maven). Некоторые из моих подмодулей на один Дир глубже, некоторые на два Дир глубже, но все они прямой подмодулей родителя, который определяет URL-адрес репозитория.таким образом, это не решает проблему в целом. Вы всегда можете объединить его с принятым ответом Clay и определить какое - то другое свойство-отлично работает и нуждается в переопределении только для случаев, когда значение от
parent.pomне достаточно хорошо. Или вы можете просто перенастроить плагин - что вы делаете только в артефактах POM (родители других подмодулей). Значение, извлеченное в свойство, вероятно, лучше, если вам это нужно на большем количестве мест, особенно когда ничего в плагине конфигурационные изменения.используя
basedirв значении была существенная часть здесь, потому что URLfile://${project.parent.relativePath}/libне хотел делать трюк (я удалил одну косую черту, чтобы сделать ее относительной). Используя свойство, которое дает мне хороший абсолютный путь,а затем относительное от него было необходимо.когда путь не URL / URI, это, вероятно, не такая проблема, чтобы отбросить
basedir.
первый ответ должен работать. В строке наследования "родитель-потомок" задается пользовательское свойство со свойством maven-default на верхнем уровне POM (в данном случае
<parent.base.directory>${project.parent.basedir}</parent.base.directory>) будет установлено, как он проходит вниз по дереву. Другими словами,${parent.base.directory}будет правильно установлен в другом дочернем POM.Примечание Вы не должны использовать
${parent.basedir}Как ваше пользовательское свойство, потому что оно совпадает с maven-default${project.parent.basedir}собственность. В противном случае он попадает в рекурсивную ошибку выражения в Maven. Вот почему я использую${parent.base.directory}в ответ.надеюсь, что это корневое решение проблемы.
Comments