AEM Guide

Cómo un proyecto Maven de AEM construye un paquete desplegable

Cómo el pom.xml padre y los módulos core, ui.apps, ui.content, ui.config y all de un proyecto AEM se combinan para producir un único paquete desplegable, y por qué el módulo all es la unidad de despliegue real.

mavenarchetypecloud-managerci-cdpackaging

Un proyecto AEM generado con el AEM Project Archetype no produce un único artefacto: produce media docena. La confusión habitual de quien llega nuevo a un proyecto AEM no es “qué hace Maven”, sino “cuál de todos estos pom.xml es el que realmente se despliega en la instancia”. La respuesta corta es: casi ninguno por separado — lo que se despliega es el resultado de un módulo concreto, all, que ensambla a los demás.

El diseño multimódulo que genera el arquetipo

Al generar un proyecto con com.adobe.aem:aem-project-archetype, obtienes un pom.xml padre (agregador) en la raíz y varios módulos hijos, cada uno con su propio pom.xml y su propio tipo de empaquetado. Los módulos estándar son:

Los detalles internos de ui.apps y ui.frontend merecen su propio artículo — aquí interesa cómo encajan todos los módulos entre sí para producir el paquete final, no cómo funciona cada uno por dentro.

Dos tipos de empaquetado: bundle vs. content-package

core es el único módulo con empaquetado jar normal: es un bundle OSGi como cualquier otro, compilado y empaquetado con el plugin de bundles habitual. El resto de módulos que producen contenido (ui.apps, ui.content, ui.config, all) usan el empaquetado content-package, construido por el filevault-package-maven-plugin (org.apache.jackrabbit). Este plugin sustituyó al antiguo content-package-maven-plugin de Adobe/Day y es actualmente el único soportado en AEM as a Cloud Service.

Cada módulo de tipo content-package declara además un packageType en la configuración del plugin:

Esta clasificación no es cosmética: la validación de paquetes de Cloud Manager la usa para rechazar builds donde, por ejemplo, un paquete marcado como application toca rutas de /content que no le corresponden.

El módulo all: cómo se ensambla el paquete final

El pom.xml de all declara dependencias de tipo zip (o jar para core) sobre los demás módulos, y la configuración del filevault-package-maven-plugin usa <embeddeds> para indicar en qué ruta de instalación debe embeberse cada uno dentro del paquete contenedor. Esta es la forma actual de hacerlo; el mecanismo antiguo, <subPackages>, está deprecado.

<!-- all/pom.xml (fragmento) -->
<plugin>
  <groupId>org.apache.jackrabbit</groupId>
  <artifactId>filevault-package-maven-plugin</artifactId>
  <extensions>true</extensions>
  <configuration>
    <group>com.myproject</group>
    <packageType>container</packageType>
    <embeddeds>
      <embedded>
        <groupId>com.myproject</groupId>
        <artifactId>myproject.core</artifactId>
        <type>jar</type>
        <target>/apps/myproject-packages/application/install</target>
      </embedded>
      <embedded>
        <groupId>com.myproject</groupId>
        <artifactId>myproject.ui.apps</artifactId>
        <type>zip</type>
        <target>/apps/myproject-packages/application/install</target>
      </embedded>
      <embedded>
        <groupId>com.myproject</groupId>
        <artifactId>myproject.ui.content</artifactId>
        <type>zip</type>
        <target>/apps/myproject-packages/content/install</target>
      </embedded>
    </embeddeds>
  </configuration>
</plugin>

Cada <embedded> necesita su correspondiente <dependency> en la misma pom.xml, apuntando a la versión del artefacto del módulo hermano (normal en un reactor Maven, donde ${project.version} mantiene todos los módulos sincronizados).

Por qué esto importa: un único artefacto desplegable

El resultado de mvn clean install en el módulo all es un único .zip instalable. En lugar de subir manualmente cuatro o cinco paquetes en el orden correcto a Package Manager, o coordinar múltiples pasos en un pipeline de despliegue, el pipeline de Cloud Manager (o cualquier script de despliegue directo) sube y activa un solo paquete. Ese único paquete es el que realmente define qué versión de código y contenido está corriendo en una instancia AEM en un momento dado.

Esto también es lo que hace determinista el build: el agregador raíz del proyecto lista los módulos en <modules>, pero es el grafo de dependencias declarado en cada pom.xml — no el orden de esa lista — lo que Maven usa para calcular el orden real de construcción del reactor.

Dónde aparece esto en la práctica