Encontrar el directorio raíz de un proyecto de reactor maven de módulos múltiples


Quiero usar el complemento maven-dependency-plugin para copiar archivos EAR de todos los submódulos de mi proyecto de módulos múltiples a un directorio que sea relativo al directorio raíz de todo el proyecto.

Es decir, mi diseño se ve similar a este, los nombres cambiaron:

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/
    ...

Y quiero que todos los archivos EAR se copien de los directorios de destino de sus respectivos módulos a {[4] } así que termino con

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/
    ...

Podría hacerlo con un camino relativo en cada módulo auricular, como entonces:

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

Pero prefiero no especificar una ruta relativa en el elemento <outputDirectory>. Preferiría algo como ${reactor.root.directory}/../to-deploy, pero no puedo encontrar nada como esto.

También, preferiría que hubiera alguna forma de heredar esta configuración de maven-dependency-plugin para no tener que especificarla para cada módulo EAR.

También intenté heredar una propiedad personalizada del pom raíz:

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

Pero cuando traté de usar ${myproject.root} en el módulo de oído POM, el ${basedir} se resolvería a la basedir del módulo auricular.

También, encontré http://labs.consol.de/lang/de/blog/maven/project-root-path-in-a-maven-multi-module-project/ donde se sugiere que cada desarrollador y presumiblemente el servidor de integración continua deben configurar el directorio raíz en un perfil.archivo xml, pero no lo considero una solución.

Entonces, ¿hay una manera fácil de encontrar la raíz de un proyecto de varios módulos?

Author: Pascal Thivent, 2010-06-21

10 answers

Desde Maven 3.3.1, puedes usar ${maven.multiModuleProjectDirectory} para este propósito. (gracias a https://stackoverflow.com/a/48879554/302789)

Editar: parece que esto solo funciona correctamente cuando tienes una carpeta .mvn en la raíz de tu proyecto.

 11
Author: Grégory Joseph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-01 11:22:56

Use ${session.executionRootDirectory}

Para el registro, ${session.executionRootDirectory} funciona para mí en archivos pom en Maven 3.0.3. Esa propiedad será el directorio en el que se está ejecutando, así que ejecute el proyecto padre y cada módulo puede obtener la ruta a ese directorio raíz.

Pongo la configuración del plugin que usa esta propiedad en el pom padre para que sea heredada. Lo uso en un perfil que solo selecciono cuando sé que voy a ejecutar Maven en el proyecto padre. De esta manera, es menos probable que use esta variable de una manera no deseada cuando corro Maven en un proyecto hijo (porque entonces la variable no sería la ruta al padre).

Por ejemplo,

<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>
 62
Author: anonymous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-13 09:40:20

Algo que he usado en mis proyectos es anular la propiedad en el submódulo poms.

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

De esta manera todavía tiene las rutas relativas, pero puede definir un complemento una vez en el módulo raíz, y sus módulos lo heredarán con la sustitución correcta para myproject.arraigar.

 20
Author: Karel Vervaeke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-13 09:07:22

Hay un plugin maven que resuelve este problema en particular: directory-maven-plugin

Asignará la ruta raíz de su proyecto a una propiedad de su elección. Véase highest-basedir objetivo en los documentos.

Por ejemplo:

<!-- 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>

Luego use ${main.basedir} en cualquier lugar de su pom padre / hijo.XML.

 16
Author: Andrejs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-01 07:52:59

Como otros han sugerido, directory-maven-plugin es el camino a seguir. Sin embargo, encontré que funciona mejor con el objetivo' directorio-de', como se describe aquí: https://stackoverflow.com/a/37965143/6498617 .

Prefiero que usar highest-basedir no funcione para mí con un proyecto multi-módulo, con poms multi-módulo anidados. El directorio-de objetivo le permite establecer una propiedad en la ruta de cualquier módulo en todo el proyecto, incluida la raíz, por supuesto. También es mucho mejor que ${sesion.executionRootDirectory}, porque siempre funciona, independientemente de si construye la raíz o un submódulo, e independientemente del directorio de trabajo actual desde el que mvn.

 4
Author: sparkyd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:17

Me encontré con un problema similar ya que necesitaba copiar archivos entre proyectos. Lo que Maven hace es lógico porque mantendrá el pom.xml instalado en el repositorio lejos del valor codificado.

Mi solución fue poner dir copiado en un artefacto Maven, luego emplear Ant para extraer/copiar

 2
Author: M.Hoang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-06 10:34:24

No soy consciente de una "buena" manera de encontrar la raíz de un proyecto de varios módulos. Pero tal vez puedas mejorar un poco tu enfoque actual.

Una primera alternativa sería crear un módulo adicional directamente debajo del proyecto raíz, declarar todas las orejas como dependencias en él y utilizar dependency:copy-dependencies para copiar las dependencias del módulo al directorio to-deploy (relativamente). Sí, la ruta seguiría siendo relativa, pero como la configuración del complemento de dependencia estaría centralizada, no lo encuentro tan molesto.

Una segunda alternativa sería usar el Complemento Maven Assembly en lugar del Complemento Maven Dependency para crear una distribución usando el formato dir (esto creará una distribución en un directorio). Esto es realmente lo que yo haría.

 1
Author: Pascal Thivent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-21 14:04:35

Otra solución sería usar una tarea ant para escribir "rootdir={{basedir}" a un destino/raíz.propiedades en el proyecto raíz, y luego use el Complemento Propiedades para leer ese archivo de nuevo. Yo no lo he probado, pero creo que debería funcionar..?

 1
Author: neu242,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-14 11:18:39

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 submódulos.

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

No funcionará para módulos anidados, pero estoy seguro de que se puede modificar para eso usando varios perfiles con diferentes exists's. (No tengo idea de por qué debería haber"../.."en la etiqueta de verificación y solo".."en la propiedad anulada en sí, pero solo funciona en por ahí.)

 0
Author: Vic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-02 10:44:55

Así que: en algún lugar de las propiedades de algún proyecto padre tengo el archivo que necesito relacionar más adelante, por qué necesito ruta absoluta en él en todas partes. Por lo tanto, lo consigo con la ayuda de 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>   

Y luego:

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

Funciona!

 0
Author: Iakov Senatov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-05 14:57:34