AEM Guide

Come un progetto Maven AEM costruisce davvero un pacchetto distribuibile

Come il pom.xml padre e i moduli core, ui.apps, ui.content, ui.config e all di un progetto AEM si combinano per produrre un unico pacchetto distribuibile, e perché il modulo all è la vera unità di deployment.

mavenarchetypecloud-managerci-cdpackaging

Un progetto AEM generato con l’AEM Project Archetype non produce un solo artefatto: ne produce mezza dozzina. La confusione tipica di chi arriva su un progetto AEM per la prima volta non è “cosa fa Maven”, ma “quale di tutti questi pom.xml è quello effettivamente distribuito sull’istanza”. La risposta breve: quasi nessuno singolarmente — ciò che viene distribuito è il risultato di un modulo specifico, all, che assembla tutti gli altri.

La struttura multimodulo generata dall’archetype

Generando un progetto con com.adobe.aem:aem-project-archetype si ottiene un pom.xml padre (aggregatore) nella radice e diversi moduli figli, ciascuno con il proprio pom.xml e il proprio tipo di packaging. I moduli standard sono:

I dettagli interni di ui.apps e ui.frontend meritano un articolo dedicato — qui interessa come tutti i moduli si incastrano tra loro per produrre il pacchetto finale, non come funziona internamente ciascuno di essi.

Due tipi di packaging: bundle vs. content-package

core è l’unico modulo con packaging jar normale: è un bundle OSGi come qualsiasi altro, compilato e impacchettato con il consueto plugin per bundle. Gli altri moduli che producono contenuto (ui.apps, ui.content, ui.config, all) usano il packaging content-package, costruito dal filevault-package-maven-plugin (org.apache.jackrabbit). Questo plugin ha sostituito il vecchio content-package-maven-plugin di Adobe/Day ed è attualmente l’unico supportato su AEM as a Cloud Service.

Ogni modulo di tipo content-package dichiara inoltre un packageType nella configurazione del plugin:

Questa classificazione non è cosmetica: la validazione dei pacchetti di Cloud Manager la usa per respingere build in cui, ad esempio, un pacchetto marcato application tocca percorsi /content che non gli competono.

Il modulo all: come viene assemblato il pacchetto finale

Il pom.xml di all dichiara dipendenze di tipo zip (o jar per core) verso gli altri moduli, e la configurazione del filevault-package-maven-plugin usa <embeddeds> per indicare in quale percorso di installazione ciascuno debba essere incorporato all’interno del pacchetto contenitore. Questo è l’approccio attuale; il vecchio meccanismo <subPackages> è deprecato.

<!-- all/pom.xml (frammento) -->
<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>

Ogni <embedded> richiede una <dependency> corrispondente nello stesso pom.xml, che punta alla versione dell’artefatto del modulo fratello (normale in un reactor Maven, dove ${project.version} mantiene tutti i moduli sincronizzati).

Perché questo è importante: un unico artefatto distribuibile

Eseguire mvn clean install sul modulo all produce un unico .zip installabile. Invece di caricare manualmente quattro o cinque pacchetti nell’ordine corretto su Package Manager, o coordinare più passaggi in una pipeline di deployment, la pipeline di Cloud Manager (o qualsiasi script di deployment diretto) carica e attiva un solo pacchetto. Quel pacchetto unico è ciò che definisce realmente quale versione di codice e contenuto sta girando su un’istanza AEM in un dato momento.

Questo è anche ciò che rende la build deterministica: l’aggregatore radice del progetto elenca i moduli sotto <modules>, ma è il grafo delle dipendenze dichiarato in ciascun pom.xml — non l’ordine di quell’elenco — che Maven usa per calcolare l’ordine effettivo di build del reactor.

Dove si presenta in pratica