Show Menu
THEMEN×

Struktur von AEM-Projekten

Machen Sie sich mit der grundlegenden Verwendung des AEM-Projektarchetyps vertraut und dem FileVault Content Maven-Plug-in , da dieser Artikel auf diesen Erkenntnissen und Konzepten aufbaut.
In diesem Artikel werden die Änderungen erläutert, die erforderlich sind, damit Adobe Experience Manager-Maven-Projekte mit AEM Cloud Service kompatibel sind, indem sichergestellt wird, dass sie die Aufteilung von veränderlichem und unveränderlichem Inhalt respektieren, dass die erforderlichen Abhängigkeiten zur Schaffung nicht widersprüchlicher, deterministischer Implementierungen festgelegt werden und dass sie in einer implementierbaren Struktur zusammengefasst sind.
AEM-Anwendungsimplementierungen müssen aus einem einzigen AEM-Paket bestehen. Dieses Paket sollte wiederum Unterpakete enthalten, die alles enthalten, was die Anwendung benötigt, um zu funktionieren, einschließlich Code, Konfiguration und unterstützenden Basisinhalten.
AEM erfordert eine Trennung von Inhalt und Code . Dies bedeutet, dass ein einzelnes Inhaltspaket nicht für beide /apps und für Laufzeitbereiche (z. B. /content , /conf , /home oder alles, was nicht /apps ist) des Repositorys bereitstellen kann. Stattdessen muss die Anwendung Code und Inhalt in separate Pakete für die Bereitstellung in AEM trennen.
Die in diesem Dokument beschriebene Paketstruktur ist mit lokalen Entwicklungsbereitstellungen und AEM Cloud Service-Bereitstellungen kompatibel.
Die in diesem Dokument beschriebenen Konfigurationen werden von AEM-Projektarchetyp 21 oder höher bereitgestellt.

Veränderliche und nicht veränderliche Bereiche des Repositorys

/apps und /libs werden als unveränderliche Bereiche von AEM betrachtet, da sie nach dem Start von AEM (d. h. zur Laufzeit) nicht mehr geändert (erstellt, aktualisiert, gelöscht) werden können . Jeder Versuch, einen unveränderlichen Bereich zur Laufzeit zu ändern, schlägt fehl.
Alles andere im Repository, /content , /conf , /var , /etc , /oak:index , /system , /tmp usw. sind alles veränderliche Bereiche, d. h. sie können zur Laufzeit geändert werden.
Wie in früheren Versionen von AEM sollten /libs nicht geändert werden. Nur der AEM-Produkt-Code darf für /libs bereitstellen.

Oak-Indizes

Oak-Indizes ( /oak:index ) werden speziell vom AEM Cloud Service-Bereitstellungsprozess verwaltet. Dies liegt daran, dass Cloud Manager warten muss, bis ein neuer Index bereitgestellt und vollständig neu identifiziert wird, bevor zum neuen Code-Bild gewechselt wird.
Aus diesem Grund müssen Oak-Indizes, obwohl sie zur Laufzeit veränderbar sind, als Code bereitgestellt werden, damit sie installiert werden können, bevor veränderbare Pakete installiert werden. Daher sind /oak:index -Konfigurationen Teil des Code-Pakets und nicht Teil des Content-Pakets, wie unten beschrieben.
Weitere Informationen zur Indizierung in AEM as a Cloud Service finden Sie im Dokument zu Inhaltssuche und -indizierung .

Pakettypen

Die Pakete sind mit ihrem deklarierten Pakettyp zu kennzeichnen.
  • Container-Pakete dürfen keinen packageType -Satz haben.
  • (Unveränderliche) Code-Pakete müssen packageType auf application setzen.
  • (Veränderliche) Inhaltspakete müssen packageType auf content setzen.
Ein vollständiges Snippet finden Sie im Abschnitt POM XML-Snippets unten.

Markieren von Paketen für die Bereitstellung durch Adobe Cloud Manager

Standardmäßig sammelt Adobe Cloud Manager alle vom Maven-Build erstellten Pakete. Da jedoch das Container-Paket ( all ) das einzige Bereitstellungs-Artefakt ist, das alle Code- und Inhaltspakete enthält, müssen wir sicherstellen, dass nur das Container-Paket ( all ) bereitgestellt wird. Um dies sicherzustellen, müssen andere Pakete, die der Maven-Build generiert, mit der FileVault Content Package Maven Plug-in-Konfiguration von <properties><cloudManagerTarget>none</cloudManageTarget></properties> gekennzeichnet werden.
Ein vollständiges Snippet finden Sie im Abschnitt POM XML-Snippets unten.

Repo Init

Repo Init enthält Anweisungen oder Skripte, mit denen JCR-Strukturen definiert werden, von allgemeinen Knotenstrukturen wie Ordnerbäumen bis hin zu Benutzern, Dienstbenutzern, Gruppen und ACL-Definitionen.
Die Hauptvorteile von Repo Init sind, dass sie implizite Berechtigungen zum Ausführen aller durch ihre Skripte definierten Aktionen haben und früh im Bereitstellungslebenszyklus aufgerufen werden, um sicherzustellen, dass alle erforderlichen JCR-Strukturen zum Zeitpunkt der Ausführung des Codes vorhanden sind.
Während Repo Init-Skripte selbst als Skripte im ui.apps -Projekt vorhanden sind, können und sollten sie zum Definieren der folgenden veränderbaren Strukturen verwendet werden:
  • Grundlegende Inhaltsstrukturen
    • Beispiele: /content/my-app , /content/dam/my-app , /conf/my-app/settings
  • Dienstbenutzer
  • Benutzer
  • Gruppen
  • ACLs
Repo Init-Skripte werden als scripts -Einträge von RepositoryInitializer -OSGi-Werkskonfigurationen gespeichert und können daher implizit vom Ausführungsmodus angesprochen werden, wodurch Unterschiede zwischen den Repo Init-Skripten der AEM-Autoren- und AEM-Veröffentlichungsdienste oder sogar zwischen den Umgebungen (Entwicklung, Staging und Produktion) berücksichtigt werden.
Beachten Sie, dass beim Definieren von Benutzern und Gruppen nur Gruppen als Teil der Anwendung betrachtet werden und hier als integraler Bestandteil ihrer Funktion definiert werden sollten. Organisationsbenutzer und -gruppen sollten weiterhin zur Laufzeit in AEM definiert werden. Wenn ein benutzerdefinierter Workflow beispielsweise einer benannten Gruppe Arbeit zuweist, sollte diese Gruppe über Repo Init in der AEM-Anwendung definiert werden. Wenn die Gruppierung jedoch nur organisatorisch ist, z. B. „Petras Team“ und „Stefans Team“, sollten diese am besten zur Laufzeit in AEM definiert und verwaltet werden.
Repo Init-Skripte müssen im Inline-Feld scripts definiert werden. Die references -Konfiguration funktioniert nicht.
Das vollständige Vokabular für Repo Init-Skripte ist in der Apache Sling Repo Init-Dokumentation verfügbar.
Ein vollständiges Snippet finden Sie im Abschnitt Repo Init-Snippets unten.

Repository-Strukturpaket

Code-Pakete müssen das FileVault Maven-Plug-in so konfigurieren, dass auf ein <repositoryStructurePackage> verwiesen wird, das die Richtigkeit struktureller Abhängigkeiten erzwingt (um sicherzustellen, dass ein Code-Paket nicht über ein anderes installiert wird). Sie können Ihr eigenes Repository-Strukturpaket für Ihr Projekt erstellen .
Dies ist nur für Code-Pakete erforderlich , d. h. für alle Pakete, die mit <packageType>application</packageType> gekennzeichnet sind.
Informationen zum Erstellen eines Repository-Strukturpakets für Ihre Anwendung finden Sie unter Entwickeln eines Repository-Strukturpakets .
Beachten Sie, dass dieses Repository-Strukturpaket für Inhaltspakete ( <packageType>content</packageType> ) nicht erforderlich ist.
Ein vollständiges Snippet finden Sie im Abschnitt POM XML-Snippets unten.

Einbetten von Unterpaketen in das Container-Paket

Inhalts- oder Code-Pakete werden in einem speziellen „Side-Car“-Ordner abgelegt und können mithilfe der <embeddeds> -Konfiguration des FileVault Maven-Plug-ins entweder auf AEM Autor, AEM Publish oder beiden installiert werden. Beachten Sie, dass die <subPackages> -Konfiguration nicht verwendet werden sollte.
Häufige Anwendungsfälle sind:
  • ACLs/Berechtigungen, die sich zwischen AEM Author- und AEM Publish-Benutzern unterscheiden
  • Konfigurationen, die nur zur Unterstützung von Aktivitäten in AEM Author verwendet werden
  • Code, wie z.B. Integrationen mit Backoffice-Systemen, die nur auf in AEM Author laufen müssen
Um AEM Author, AEM Publish oder beides als Ziel festzulegen, wird das Paket in das all -Container-Paket an einem bestimmten Ordnerspeicherort im folgenden Format eingebettet:
/apps/<app-name>-packages/(content|application)/install(.author|.publish)?
Aufschlüsselung dieser Ordnerstruktur:
  • Der Ordner der ersten Ebene muss /apps sein.
  • Der Ordner der zweiten Ebene stellt die Anwendung dar, wobei -packages an den Ordnernamen angehängt wird. Häufig gibt es nur einen einzigen Ordner der zweiten Ebene, unter dem alle Unterpakete eingebettet sind. Es können jedoch beliebig viele Ordner der zweiten Ebene erstellt werden, um die logische Struktur der Anwendung bestmöglich darzustellen:
    • /apps/my-app-packages
    • /apps/my-other-app-packages
    • /apps/vendor-packages
    Konventionell werden eingebettete Unterpakete mit dem Suffix -packages benannt. Dadurch wird sichergestellt, dass der Bereitstellungs-Code und die Inhaltspakete nicht in den Zielordnern eines Unterpakets /apps/<app-name>/... bereitgestellt werden, was zu destruktiven und zyklischen Installationsverhalten führt.
  • Der Ordner der dritten Ebene muss application oder content sein.
    • Der application -Ordner enthält Code-Pakete
    • Der content -Ordner enthält Inhaltspakete Dieser Ordnername muss den Pakettypen der darin enthaltenen Pakete entsprechen.
  • Der Ordner der vierten Ebene enthält die Unterpakete und muss einer der folgenden sein:
    • install zur Installation auf beiden , AEM Author und AEM Publish
    • install.author zur Installation nur auf AEM Author
    • install.publish zur Installation nur auf AEM Publish Beachten Sie, dass nur install.author und install.publish unterstützte Ziele sind. Andere Ausführungsmodi werden nicht unterstützt.
Beispielsweise kann eine Bereitstellung, die AEM Author- und Publish-spezifische Pakete enthält, wie folgt aussehen:
  • Container-Paket all bettet die folgenden Pakete ein, um ein einzelnes Bereitstellungsartefakt zu erstellen
    • ui.apps eingebettet in /apps/my-app-packages/application/install stellt Code für AEM Author und AEM Publish bereit
    • ui.apps.author eingebettet in /apps/my-app-packages/application/install.author stellt Code nur für AEM Author bereit
    • ui.content eingebettet in /apps/my-app-packages/content/install stellt Inhalte und Konfiguration für AEM Author und AEM Publish bereit
    • ui.content.publish eingebettet in /apps/my-app-packages/content/install.publish stellt Inhalte und Konfiguration nur für AEM Publish bereit
Ein vollständiges Snippet finden Sie im Abschnitt POM XML-Snippets unten.

Filterdefinition des Container-Pakets

Aufgrund der Einbettung von Code- und Inhalts-Unterpaketen in das Container-Paket müssen die eingebetteten Zielpfade zu filter.xml des Container-Projekts hinzugefügt werden, um sicherzustellen, dass die eingebetteten Pakete beim Erstellen im Container-Paket enthalten sind.
Fügen Sie einfach die <filter root="/apps/<my-app>-packages"/> -Einträge für alle Ordner der zweiten Ebene hinzu, die zu bereitzustellende Unterpakete enthalten.
Ein vollständiges Snippet finden Sie im Abschnitt POM XML-Snippets unten.

Einbetten von Drittanbieter-Paketen

Alle Pakete müssen über das öffentliche Maven-Artefakt-Repository von Adobe oder ein öffentlich zugängliches, referenzierbares Maven-Artefakt-Repository von Drittanbietern verfügbar sein.
Wenn sich die Pakete von Drittanbietern im öffentlichen Maven-Artefakt-Repository von Adobe befinden, ist für Adobe Cloud Manager keine weitere Konfiguration erforderlich, um die Artefakte aufzulösen.
Wenn sich die Pakete von Drittanbietern in einem öffentlichen Maven-Artefakt-Repository von Drittanbietern befinden, muss dieses Repository in der pom.xml des Projekts registriert und gemäß der oben beschriebenen Methode eingebettet werden. Wenn für die Anwendung/den Connector eines Drittanbieters sowohl Code- als auch Inhaltspakete erforderlich sind, muss jedes an den richtigen Speicherorten in Ihrem Container ( all )-Paket eingebettet sein.
Das Hinzufügen von Maven-Abhängigkeiten folgt den Standardpraktiken von Maven, und das Einbetten von Artefakten von Drittanbietern (Code- und Inhaltspakete) ist oben beschrieben .
Ein vollständiges Snippet finden Sie im Abschnitt POM XML-Snippets unten.

Paketabhängigkeiten zwischen den ui.apps von ui.content -Paketen

Um eine ordnungsgemäße Installation der Pakete sicherzustellen, wird empfohlen, Abhängigkeiten zwischen Paketen zu erstellen.
Die allgemeine Regel ist, dass Pakete mit veränderlichem Inhalt ( ui.content ) vom unveränderlichen Code ( ui.apps ) abhängen sollten, der die Wiedergabe und Verwendung des veränderlichen Inhalts unterstützt.
Eine wichtige Ausnahme von dieser allgemeinen Regel ist, wenn das unveränderliche Code-Paket ( ui.apps oder jedes andere) nur OSGi-Bundles enthält. Ist dies der Fall sollte kein AEM-Paket eine Abhängigkeit angeben. Dies liegt daran, dass unveränderliche Code-Pakete, die nur OSGi-Bundles enthalten, nicht bei AEM Package Manager registriert sind, sodass jedes davon abhängige AEM-Paket eine unbefriedigende Abhängigkeit aufweist und nicht installiert werden kann.
Ein vollständiges Snippet finden Sie im Abschnitt POM XML-Snippets unten.
Die üblichen Muster für Abhängigkeiten von Inhaltspaketen sind:

Abhängigkeiten von einfachen Bereitstellungspaketen

Im einfachen Fall hängt das veränderliche Inhaltspaket ui.content vom unveränderlichen Code-Paket ui.apps ab.
  • all hat keine Abhängigkeiten
    • ui.apps hat keine Abhängigkeiten
    • ui.content hängt von ui.apps ab

Abhängigkeiten von komplexen Bereitstellungspaketen

Komplexe Implementierungen gehen über den einfachen Fall hinaus und legen Abhängigkeiten zwischen den entsprechenden veränderbaren Inhalten und unveränderlichen Code-Paketen fest. Abhängigkeiten können bei Bedarf auch zwischen unveränderlichen Code-Paketen festgelegt werden.
  • all hat keine Abhängigkeiten
    • ui.apps.common hat keine Abhängigkeiten
    • ui.apps.site-a hängt von ui.apps.common ab
    • ui.content.site-a hängt von ui.apps.site-a ab
    • ui.apps.site-b hängt von ui.apps.common ab
    • ui.content.site-b hängt von ui.apps.site-b ab

Lokale Entwicklung und Bereitstellung

Die in diesem Artikel beschriebenen Projektstrukturen und -organisationen sind mit AEM-Instanzen für die lokale Entwicklung vollständig kompatibel .

POM-XML-Snippets

Im Folgenden finden Sie Maven pom.xml -Konfigurations-Snippets, die zu Maven-Projekten hinzugefügt werden können, um sie an die oben genannten Empfehlungen anzupassen.

Pakettypen

Code- und Inhaltspakete, die als Unterpakete bereitgestellt werden, müssen abhängig davon, was sie enthalten, application oder content als Pakettyp deklarieren.

Container-Pakettypen

Das Container-Projekt all/pom.xml deklariert keinen <packageType> .

(Unveränderliche) Code-Pakettypen

Code-Pakete müssen ihren packageType auf application setzen.
In der ui.apps/pom.xml deklariert die <packageType>application</packageType> -Build-Konfigurationsanweisung der filevault-package-maven-plugin -Plug-in-Deklaration den Pakettyp.
...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.jackrabbit</groupId>
      <artifactId>filevault-package-maven-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
        <group>${project.groupId}</group>
        <name>${my-app.ui.apps}</name>
        <packageType>application</packageType>
        <accessControlHandling>merge</accessControlHandling>
        <properties>
          <cloudManagerTarget>none</cloudManagerTarget>
        </properties>
      </configuration>
    </plugin>
    ...

(Veränderliche) Code-Pakettypen

Inhaltspakete müssen ihren packageType auf content setzen.
In der ui.content/pom.xml deklariert die <packageType>content</packageType> -Build-Konfigurationsanweisung der filevault-package-maven-plugin -Plug-in-Deklaration den Pakettyp.
...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.jackrabbit</groupId>
      <artifactId>filevault-package-maven-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
        <group>${project.groupId}</group>
        <name>${my-app.ui.content}</name>
        <packageType>content</packageType>
        <accessControlHandling>merge</accessControlHandling>
        <properties>
          <cloudManagerTarget>none</cloudManagerTarget>
        </properties>
      </configuration>
    </plugin>
    ...

Markieren von Paketen für die Bereitstellung über Adobe Cloud Manager

Fügen Sie in jedem Projekt, das ein Paket generiert, mit Ausnahme des Container-Projekts ( all ), <cloudManagerTarget>none</cloudManagerTarget> der <properties> -Konfiguration der filevault-package-maven-plugin -Plug-in-Deklaration hinzu, um sicherzustellen, dass sie nicht von Adobe Cloud Manager bereitgestellt werden. Das Container-Paket ( all ) sollte das Einzelpaket sein, das über Cloud Manager bereitgestellt wird. Dadurch werden alle erforderlichen Code- und Inhaltspakete eingebettet.
...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.jackrabbit</groupId>
      <artifactId>filevault-package-maven-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
        ...
        <properties>
          <cloudManagerTarget>none</cloudManagerTarget>
        </properties>
      </configuration>
    </plugin>
    ...

Repo Init

Repo Init-Skripte, die die Repo Init-Skripte enthalten, werden in der RepositoryInitializer -OSGi-Werkskonfiguration über die scripts -Eigenschaft definiert. Da diese Skripts in OSGi-Konfigurationen definiert sind, können sie mithilfe der üblichen ../config.<runmode> -Ordnersemantik problemlos vom Runmode erfasst werden.
Da es sich bei Skripten normalerweise um mehrzeilige Deklarationen handelt, ist es einfacher, sie in der .config -Datei zu definieren als im XML-Basisformat sling:OsgiConfig .
/apps/my-app/config.author/org.apache.sling.jcr.repoinit.RepositoryInitializer-author.config
scripts=["
    create service user my-data-reader-service

    set ACL on /var/my-data
        allow jcr:read for my-data-reader-service
    end

    create path (sling:Folder) /conf/my-app/settings
"]

Die scripts -OSGi-Eigenschaft enthält Anweisungen, die in der Repo Init-Sprache von Apache Sling definiert sind.

Repository-Strukturpaket

Fügen Sie in ui.apps/pom.xml und allen anderen pom.xml , die ein Code-Paket ( <packageType>application</packageType> ) deklarieren, die folgende Repository-Strukturpaketkonfiguration zum FileVault Maven-Plug-in hinzu. Sie können Ihr eigenes Repository-Strukturpaket für Ihr Projekt erstellen .
...
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.jackrabbit</groupId>
      <artifactId>filevault-package-maven-plugin</artifactId>
      <extensions>true</extensions>
      <configuration>
        ...
        <repositoryStructurePackages>
          <repositoryStructurePackage>
              <groupId>${project.groupId}</groupId>
              <artifactId>ui.apps.structure</artifactId>
              <version>${project.version}</version>
          </repositoryStructurePackage>
        </repositoryStructurePackages>
      </configuration>
    </plugin>
    ...

Einbetten von Unterpaketen in das Container-Paket

Fügen Sie in all/pom.xml der filevault-package-maven-plugin -Plug-in-Deklaration die folgenden <embeddeds> -Anweisungen hinzu. Denken Sie daran, die <subPackages> -Konfiguration nicht zu verwenden, da dies die Unterpakete in /etc/packages anstatt in /apps/my-app-packages/<application|content>/install(.author|.publish)? einschließt.
...
<plugin>
  <groupId>org.apache.jackrabbit</groupId>
  <artifactId>filevault-package-maven-plugin</artifactId>
  <extensions>true</extensions>
  <configuration>
      ...
      <embeddeds>

          <!-- Include the application's ui.apps and ui.content packages -->
          <!-- Ensure the artifactIds are correct -->

          <!-- Code package that deploys to BOTH AEM Author and AEM Publish -->
          <embedded>
              <groupId>${project.groupId}</groupId>
              <artifactId>my-app.ui.apps</artifactId>
              <type>zip</type>
              <target>/apps/my-app-packages/application/install</target>
          </embedded>

          <!-- Code package that deploys ONLY to AEM Author -->
          <embedded>
              <groupId>${project.groupId}</groupId>
              <artifactId>my-app.ui.apps.author</artifactId>
              <type>zip</type>
              <target>/apps/my-app-packages/application/install.author</target>
          </embedded>

          <!-- Content package that deploys to BOTH AEM Author and AEM Publish -->
          <embedded>
              <groupId>${project.groupId}</groupId>
              <artifactId>my-app.ui.content</artifactId>
              <type>zip</type>
              <target>/apps/my-app-packages/content/install</target>
          </embedded>

          <!-- Content package that deploys ONLY to AEM Publish -->
          <embedded>
              <groupId>${project.groupId}</groupId>
              <artifactId>my-app.ui.content.publish-only</artifactId>
              <type>zip</type>
              <target>/apps/my-app-packages/content/install.publish</target>
          </embedded>

          <!-- Include any other extra packages such as AEM WCM Core Components -->
          <embedded>
              <groupId>com.adobe.cq</groupId>
              <!-- Not to be confused; WCM Core Components' Code package's artifact is named `.content` -->
              <artifactId>core.wcm.components.content</artifactId>
              <type>zip</type>
              <target>/apps/vendor-packages/application/install</target>
          </embedded>

          <embedded>
              <groupId>com.adobe.cq</groupId>
              <!-- Not to be confused; WCM Core Components' Content package's artifact is named `.conf` -->
              <artifactId>core.wcm.components.conf</artifactId>
              <type>zip</type>
              <target>/apps/vendor-packages/content/install</target>
          </embedded>
      <embeddeds>
  </configuration>
</plugin>
...

Filterdefinition des Container-Pakets

In der filter.xml des all -Projekts ( all/src/main/content/jcr_root/META-INF/vault/definition/filter.xml ) schließen Sie alle -packages -Ordner ein, die bereitzustellende Unterpakete enthalten:
<filter root="/apps/my-app-packages"/>

Wenn mehrere /apps/*-packages in den eingebetteten Zielen verwendet werden, müssen sie hier alle aufgezählt werden.

Maven-Repositorys von Drittanbietern

Das Hinzufügen weiterer Maven-Repositorys kann die Maven-Erstellungszeiten verlängern, da zusätzliche Maven-Repositorys auf Abhängigkeiten überprüft werden.
Fügen Sie im pom.xml des Reaktorprojekts alle erforderlichen öffentlichen Maven-Repository-Anweisungen von Drittanbietern hinzu. Die vollständige <repository> -Konfiguration sollte beim Repository-Drittanbieter erhältlich sein.
<repositories>
  ...
  <repository>
      <id>3rd-party-repository</id>
      <name>Public 3rd Party Repository</name>
      <url>https://repo.3rdparty.example.com/...</url>
      <releases>
          <enabled>true</enabled>
          <updatePolicy>never</updatePolicy>
      </releases>
      <snapshots>
          <enabled>false</enabled>
      </snapshots>
  </repository>
  ...
</repositories>

Paketabhängigkeiten zwischen den ui.apps von ui.content -Paketen

Fügen Sie in ui.content/pom.xml der filevault-package-maven-plugin -Plug-in-Deklaration die folgenden <dependencies> -Anweisungen hinzu.
...
<plugin>
  <groupId>org.apache.jackrabbit</groupId>
  <artifactId>filevault-package-maven-plugin</artifactId>
  <extensions>true</extensions>
  <configuration>
      ...
      <dependencies>
        <!-- Declare the content package dependency in the ui.content/pom.xml on the ui.apps project -->
        <dependency>
            <groupId${project.groupId}</groupId>
            <artifactId>my-app.ui.apps</artifactId>
            <version>${project.version}</version>
        </dependency>
      </dependencies>
    ...
  </configuration>
</plugin>
...

Bereinigen des Zielordners des Container-Projekts

Fügen Sie all/pom.xml das maven-clean-plugin -Plug-in hinzu, welches den Zielordner vor einem Maven-Build bereinigt.
<plugins>
  ...
  <plugin>
    <artifactId>maven-clean-plugin</artifactId>
    <executions>
      <execution>
        <id>auto-clean</id>
        <!-- Run at the beginning of the build rather than the default, which is after the build is done -->
        <phase>initialize</phase>
        <goals>
          <goal>clean</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
  ...
</plugins>