Propiedad Maven2 que indica el directorio principal

Tengo un proyecto de varios módulos, como este:

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

Necesito definir un conjunto de propiedades (que dependen del entorno en el que quiero lanzar mi proyecto) en Maven2. No usaré ya que hay muchas propiedades … Por lo tanto, uso el plugin Propiedades Maven2 .

Los archivos de propiedades se encuentran en el directorio main-project/ . ¿Cómo puedo establecer el directorio correcto en el archivo pom.xml principal, para especificar a los elementos secundarios dónde encontrar el archivo de propiedades?

  org.codehaus.mojo properties-maven-plugin 1.0-alpha-1   initialize  read-project-properties    ???/env_${env}.properties      

Si configuro solo env_${env}.properties , cuando Maven2 comstack el primer módulo, no encontrará el archivo main-project/env_dev.properties . Si configuro ../env_${env}.properties , se generará un error en el nivel principal, o en cualquier nivel de submódulo …

Intente establecer una propiedad en cada pom para encontrar el directorio principal del proyecto.

En el padre:

  
${project.basedir}

En los niños:

  
${project.parent.basedir}

En los nietos:

  
${project.parent.parent.basedir}

Encontré una solución para resolver mi problema: busco en los archivos de propiedades usando el complemento Groovy Maven.

Como mi archivo de propiedades está necesariamente en el directorio actual, en ../ o en .. / .., escribí un pequeño código de Groovy que verifica estas tres carpetas.

Aquí está el extracto de mi pom.xml:

   org.codehaus.groovy.maven gmaven-plugin 1.0-rc-5   validate  execute    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();        org.codehaus.mojo properties-maven-plugin 1.0-alpha-1   initialize  read-project-properties    ${env-properties-file-by-groovy}      

Esto está funcionando, pero realmente no me gusta.

Entonces, si tiene una mejor solución, ¡no dude en publicarla!

Entonces el problema es que no se puede obtener la ruta absoluta a un directorio padre en maven.

He oído hablar de esto como un antipatrón , pero para cada antipatrón hay un uso real y legítimo, y estoy harto de que maven me diga que solo puedo seguir sus patrones.

Entonces el trabajo que encontré fue usar antrun. Pruebe esto en el pom.xml hijo:

  org.apache.maven.plugins maven-antrun-plugin 1.7   getMainBaseDir validate  run   true          

Si ejecuta mvn verify que vea algo como esto:

 main: [echo] main.basedir=C:\src\parent.project.dir.name 

Luego puedes usar ${main.basedir} en cualquiera de los otros complementos, etc. Me tomó un tiempo resolver esto, así que espero que ayude a alguien más.

Use directory-maven-plugin con el objective directory-of .

A diferencia de otras sugerencias:

  • Esta solución funciona para proyectos de múltiples módulos.
  • Funciona ya sea que construyas el proyecto completo o un submódulo.
  • Funciona ya sea que ejecute maven desde la carpeta raíz o un submódulo.
  • ¡No es necesario establecer una propiedad de ruta relativa en todos y cada uno de los submódulos!

El complemento le permite establecer una propiedad de su elección en la ruta absoluta de cualquiera de los módulos del proyecto. En mi caso, lo configuré para el módulo raíz … En mi proyecto root pom:

   org.commonjava.maven.plugins directory-maven-plugin 0.1   directories  directory-of  initialize  myproject.basedir  com.my.domain my-root-artifact      

Desde ese momento, $ {myproject.basedir} en cualquier submódulo pom siempre tiene la ruta del módulo raíz del proyecto. Y, por supuesto, puede establecer la propiedad en cualquier módulo, no solo en la raíz …

En mi caso, funciona así:

 ...  ${project.parent.relativePath}/..  ...  org.codehaus.mojo properties-maven-plugin 1.0-alpha-1   initialize  read-project-properties    ${main_dir}/maven_custom.properties      

El siguiente pequeño perfil funcionó para mí. Necesitaba tal configuración para CheckStyle, que puse en el directorio config en la raíz del proyecto, para poder ejecutarlo desde el módulo principal y desde los submódulos.

  root-dir   ${project.basedir}/../../config/checkstyle.xml    ${project.basedir}/../config   

No funcionará para módulos nesteds, pero estoy seguro de que se puede modificar para eso usando varios perfiles con diferentes exists . (No tengo idea de por qué debería haber “../ ..” en la etiqueta de verificación y solo “..” en la propiedad sobrescrita, pero funciona solo de esa manera).

Otra alternativa:

en el pom padre, use:

  ${session.executionRootDirectory}  

En los poms de los niños, puedes hacer referencia a esta variable.

Advertencia principal: Te obliga a ejecutar siempre el comando desde el directorio padre principal de pom. Luego, si desea ejecutar comandos (prueba, por ejemplo) solo para algún módulo específico, use esta syntax:

prueba mvn –proyectos

La configuración de surefire para parametrizar una variable “path_to_test_data” puede ser:

  org.apache.maven.plugins maven-surefire-plugin ${surefire.plugin.version}   ${rootDir/../testdata}    

Encontré una solución para resolver este problema: use $ {parent.relativePath}

  xxx xxx 1.0-SNAPSHOT ..    ${parent.relativePath}/src/main/filters/filter-${env}.properties    src/main/resources true    

Estás en el proyecto C, el proyecto C es el submódulo de B y B es el submódulo de A. Intentas llegar al directorio del src/test/config/etc del módulo C. D también es un submódulo de A. La siguiente expresión lo hace posible para obtener la ruta URI:

 -Dparameter=file:/${basedir}/../../D/src/test/config/etc 
   org.codehaus.groovy.maven gmaven-plugin 1.0   validate  execute    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 }       org.codehaus.mojo properties-maven-plugin 1.0-alpha-2   initialize  read-project-properties    ${parentdir}/build.properties      ... 

En una respuesta a otra pregunta , mostré cómo el plugin maven-properties-plugin podría extenderse para usar descriptores de propiedad externos definidos en las dependencias de Maven.

Puede extender esa idea para tener varios archivos descriptores, cada uno con el nombre del entorno como parte del artifactId, que contiene $ {env} .properties. Luego puede usar la propiedad para seleccionar el archivo jar y propiedades apropiado, por ejemplo:

  org.codehaus.mojo properties-ext-maven-plugin 0.0.1   read-properties initialize  read-project-properties       ${env}.properties      some.descriptor.group env-${env}-descriptor 0.0.1    

Simplemente mejoré la secuencia de comandos Groovy desde arriba para escribir la propiedad en el archivo de propiedades principal raíz:

 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() 

Accedí al directorio anterior utilizando $ {basedir} .. \ src \

¿ ../../env_${env}.properties../../env_${env}.properties ?

Normalmente hacemos lo siguiente cuando el módulo2 está en el mismo nivel que los submódulos

  ../sub-module1 ../sub-module2 ../sub-module3  

Creo que el … / … te dejaría saltar dos niveles. De lo contrario, es posible que desee ponerse en contacto con los autores de los complementos y ver si se trata de un problema conocido.

Creo que si usa el patrón de extensión utilizado en el ejemplo de findbugs plugin & multimodule, puede establecer propiedades globales relacionadas con rutas absolutas. Utiliza una parte superior

ejemplo para multi módulo

El pom de nivel superior tiene un proyecto de comstackción de configuración no relacionado y una aplicación principal para los módulos del proyecto de varios módulos. La aplicación principal utiliza la extensión para vincularse al proyecto build-config y obtener recursos de ella. Esto se usa para llevar archivos de configuración comunes a los módulos. Puede ser un conducto para las propiedades también. Puede escribir el dir superior en un archivo de propiedades consumido por build-config. (parece demasiado complejo)

El problema es que se debe agregar un nuevo nivel superior al proyecto de varios módulos para que esto funcione. Traté de dar un paso al costado con un proyecto de configuración de construcción realmente no relacionado, pero era complicado y parecía quebradizo.

Esto amplía la respuesta de romaintaz, que es impresionante porque resuelve el problema y también señala claramente la funcionalidad que falta de maven. Cogí una versión posterior del complemento y agregué el caso donde el proyecto podría tener más de 3 niveles de profundidad.

   ..  org.codehaus.gmaven groovy-maven-plugin 2.0  ..   

Decidí no usar una propiedad para definir el nombre del archivo. Tenga en cuenta que si build.properties no se encuentra, esto girará para siempre. Agregué una detección .git dir, pero no quería complicar demasiado la respuesta, por lo que no se muestra aquí.

   org.codehaus.gmaven groovy-maven-plugin   validate  execute    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}"; } }      

Necesitaba resolver un problema similar para el repository local ubicado en el proyecto principal del proyecto de varios módulos. Esencialmente, la ruta real era ${basedir} / lib. Finalmente me decidí por esto en mi parent.pom :

  local-maven-repo file:///${basedir}/${project.parent.relativePath}/lib  

Esa base siempre muestra el módulo local actual, no hay forma de obtener el camino al proyecto “maestro” (la vergüenza de Maven). Algunos de mis submódulos son un directorio más profundo, algunos son dos directorios más profundos, pero todos ellos son submódulos directos del elemento principal que define el URL del repository.

Entonces esto no resuelve el problema en general. Siempre puede combinarlo con la respuesta aceptada de Clay y definir alguna otra propiedad: funciona bien y debe redefinirse solo para los casos en que el valor de parent.pom no sea lo suficientemente bueno. O simplemente puede reconfigurar el complemento, que solo hace en artefactos POM (padres de otros submódulos). El valor extraído en la propiedad probablemente sea mejor si lo necesita en más lugares, especialmente cuando no cambia nada en la configuración del complemento.

El uso de basedir en el valor fue la parte esencial aquí, porque el file://${project.parent.relativePath}/lib URL file://${project.parent.relativePath}/lib no quería hacer el truco (eliminé una barra para hacerlo relativo). Usar propiedad que me da una buena ruta absoluta y luego ir relativa desde allí era necesaria.

Cuando la ruta no es URL / URI, probablemente no sea un problema soltar basedir .

La primera respuesta debería funcionar. En la línea de herencia padre-hijo, la propiedad definida por el usuario se establece con una propiedad maven-default en el POM de nivel superior (en este caso, ${project.parent.basedir} ) se establecerá a medida que atraviesa el árbol. En otras palabras, ${parent.base.directory} se establecerá correctamente en diferentes POM secundarios.

Tenga en cuenta que no debe usar ${parent.basedir} como su propiedad definida por el usuario porque es la misma que la propiedad maven-default ${project.parent.basedir} . De lo contrario, entra en error de expresión recursiva en maven. Es por eso que uso ${parent.base.directory} en la respuesta.

Espero que esta sea la solución raíz al problema.