Show Menu
トピック×

AEM プロジェクトの構造

AEM プロジェクトアーキタイプ の基本的な使用法と、 FileVault コンテンツパッケージ Maven プラグイン について説明します。この記事では、これらの概念の理解を前提としています。
この記事では、AEM as a Cloud Service との互換性を保つために Adobe Experience Manager Maven プロジェクトに必要な変更について説明します。互換性を保つには、プロジェクトが可変コンテンツと不変コンテンツの分離に従っていること、矛盾のない決定論的なデプロイメントの作成に必要な依存関係が設定されていること、デプロイ可能な構造にプロジェクトがパッケージ化されていることが必要です。
AEM アプリケーションのデプロイメントは、単一の AEM パッケージで構成する必要があります。次に、そのパッケージには、コード、設定、補助的なベースラインコンテンツなど、アプリケーションが機能するのに必要なあらゆるもので構成されるサブパッケージが含まれている必要があります。
AEM では、 コンテンツ ​と​ コード ​を分離する必要があります。つまり、リポジトリの /apps と実行時に書き込み可能な領域(例: /content /conf /home 、その他 /apps 以外のすべて)の​ 両方 ​に 1 つのコンテンツパッケージをデプロイすることは​ できません 。代わりに、アプリケーションを AEM にデプロイするには、コードとコンテンツを別々のパッケージに分離する必要があります。
このドキュメントで概要を説明しているパッケージ構造は、ローカル開発デプロイメントと AEM as a Cloud Service デプロイメントの​ 両方 ​に対応しています。
このドキュメントで概要を説明している設定は、 AEM プロジェクト Maven アーキタイプ 21 以降 で提供されます。

リポジトリの可変領域と不変領域

/apps /libs は AEM の​ 不変 ​領域と見なされます。AEM の起動後(例:実行時)に変更(作成、更新、削除)できないからです。実行時に不変領域を変更しようとすると失敗します。
リポジトリ内のそれ以外の領域( /content /conf /var /etc /oak:index /system /tmp 、など)はすべて​ 可変 ​領域です。つまり、実行時に変更できます。
以前のバージョンの AEM と同様に、 /libs は変更しないでください。 /libs にデプロイできるのは、AEM 製品コードだけです。

パッケージタイプ

パッケージは、宣言済みのパッケージタイプでマークされる必要があります。
  • コンテナパッケージには packageType を設定できません。
  • コード(不変)パッケージは、 packageType application に設定する必要があります。
  • コンテンツ(可変)パッケージは、 packageType content に設定する必要があります。
詳しくは、 Apache Jackrabbit FileVault - Package Maven Plugin のドキュメントと、以下の FileVault Maven 設定スニペット を参照してください。
完全なスニペットについては、この後の POM XML スニペット の節を参照してください。

Adobe Cloud Manager によるデプロイメント用のパッケージのマーク

デフォルトでは、Adobe Cloud Manager は Maven ビルドで生成されたすべてのパッケージを組み込みますが、コンテナ( all )パッケージはすべてのコードパッケージおよびコンテンツパッケージを含んだ単一のデプロイメントアーティファクトなので、必ず、コンテナ( all )パッケージ​ のみ ​をデプロイします。これを確実におこなうには、Maven ビルドで生成される他のパッケージを、 <properties><cloudManagerTarget>none</cloudManageTarget></properties> という FileVault コンテンツパッケージ Maven プラグイン設定でマークする必要があります。
完全なスニペットについては、この後の POM XML スニペット の節を参照してください。

Repo Init

Repo Init は、フォルダーツリーなどの一般的なノード構造から、ユーザー、サービスユーザー、グループ、ACL 定義まで、JCR 構造を定義する手順(スクリプト)を提供します。
Repo Init の主な利点は、スクリプトで定義されたすべてのアクションを実行する暗黙の権限があり、デプロイのライフサイクルの早い段階で呼び出され、必要な JCR 構造がすべて実行されることです。
Repo Init スクリプト自体はスクリプトとして ui.apps プロジェクト内に存在しますが、スクリプトは次の可変構造を定義するために使用でき、また使用する必要があります。
  • ベースラインコンテンツの構造
    • 例: /content/my-app , /content/dam/my-app , /conf/my-app/settings
  • サービスユーザー
  • ユーザー
  • グループ
  • ACL
Repo Init scripts are stored as scripts entries of RepositoryInitializer OSGi factory configurations, and thus, can be implicitly targeted by runmode, allowing for differences between AEM Author and AEM Publish Services' Repo Init scripts, or even between Envs (Dev, Stage and Prod).
ユーザーとグループを定義する場合、グループのみがアプリケーションの一部と見なされ、またここで定義される必要がある機能に不可欠なものと見なされます。組織のユーザーとグループは、実行時に AEM で定義する必要があります。例えば、カスタムワークフローが名前付きのグループに作業を割り当てる場合、そのグループは AEM アプリケーションの Repo Init を介して定義する必要がありますが、グループ化が単なる組織(「Wendy のチーム」や「Sean のチーム」など)の場合、これらは最適な定義で、実行時に AEM で管理されます。
Repo Init スクリプトは、インライン scripts フィールドで定義する​ 必要があり references 設定は機能しません。
Repo Init スクリプトの全語彙は、 Apache Sling Repo Init ドキュメント で入手できます。
完全なスニペットについては、この後の Repo Init スニペット の節を参照してください。

リポジトリ構造パッケージ

コードパッケージでは、(あるコードパッケージが別のコードパッケージをオーバーライドしないように)正しい構造的依存関係を確保する <repositoryStructurePackage> を参照するように、FileVault Maven プラグインの設定を指定する必要があります。 プロジェクト用に独自のリポジトリ構造パッケージを作成 することができます。
これは、コードパッケージ( <packageType>application</packageType> でマークされた任意のパッケージ)に​ のみ必要 ​です。
アプリケーション用のリポジトリ構造パッケージの作成方法については、 リポジトリ構造パッケージの作成 を参照してください。
なお、コンテンツパッケージ( <packageType>content</packageType> )には、このリポジトリ構造パッケージは必要​ ありません
完全なスニペットについては、この後の POM XML スニペット の節を参照してください。

コンテナパッケージへのサブパッケージの埋め込み

コンテンツパッケージまたはコードパッケージは、特別な「サイドカー」フォルダーに格納され、FileVault Maven プラグインの <embeddeds> 設定を使用して、AEM オーサーと AEM パブリッシュのどちらか一方または両方へのインストールの対象とすることができます。 <subPackages> 設定は使用しないでください。
一般的な使用例は次のとおりです。
  • AEM オーサーユーザーと AEM パブリッシュユーザーで異なる ACL/権限
  • AEM オーサーでのみアクティビティをサポートするために使用される設定
  • AEM オーサーでのみ実行する必要があるコード(バックオフィスシステムとの統合など)
AEM オーサーか AEM パブリッシュまたはその両方をターゲットにするには、パッケージを次の形式で all コンテナパッケージ内の特別なフォルダー位置に埋め込みます。
/apps/<app-name>-packages/(content|application)/install(.author|.publish)?
このフォルダー構造の詳細は次のとおりです。
  • 第 1 レベルのフォルダーは /apps に​ する必要があります
  • 第 2 レベルのフォルダーは、フォルダー名の末尾に -packages が付いたアプリケーションを表します。多くの場合、すべてのサブパッケージが配下に埋め込まれる第 2 レベルのフォルダーは 1 つだけですが、アプリケーションの論理構造を最も適切に表すために、第 2 レベルのフォルダーをいくつでも作成できます。
    • /apps/my-app-packages
    • /apps/my-other-app-packages
    • /apps/vendor-packages
    慣例により、サブパッケージが埋め込まれるフォルダーの名前には、 -packages というサフィックスが付けられます。これにより、デプロイメントコードパッケージとコンテンツパッケージが任意のサブパッケージの対象フォルダー /apps/<app-name>/... にデプロイ​ されなくなり 、破壊的な循環インストール動作を避けることができます。
  • 第 3 レベルのフォルダーは、 application content のどちらかにする必要があります。
    • application フォルダーにはコードパッケージが格納されます。
    • The content folder holds content packages This folder name must correspond to the package types of the packages it contains.
  • 第 4 レベルのフォルダーはサブパッケージを格納するもので、次のいずれかにする必要があります。
    • install :AEM オーサーと AEM パブリッシュの​ 両方 ​にインストールする場合
    • install.author :AEM オーサーに​ のみ ​インストールする場合
    • install.publish :AEM パブリッシュに​ のみ ​インストールする場合。なお、サポートされているターゲットは install.author install.publish のみです。その他の実行モードはサポートされて​ いません
例えば、AEM オーサーおよびパブリッシュに固有のパッケージを含んだデプロイメントは、次のようになります。
  • all コンテナパッケージに次のパッケージが埋め込まれて、単一のデプロイメントアーティファクトが作成されます。
    • ui.apps /apps/my-app-packages/application/install に埋め込まれると、AEM オーサーと AEM パブリッシュの両方にコードがデプロイされます
    • ui.apps.author /apps/my-app-packages/application/install.author に埋め込まれると、AEM オーサーにのみコードがデプロイされます
    • ui.content /apps/my-app-packages/content/install に埋め込まれると、AEM オーサーと AEM パブリッシュの両方にコンテンツと設定がデプロイされます
    • ui.content.publish /apps/my-app-packages/content/install.publish に埋め込まれると、AEM パブリッシュにのみコンテンツと設定がデプロイされます
完全なスニペットについては、この後の POM XML スニペット の節を参照してください。

コンテナパッケージのフィルター定義

コンテナパッケージにコードおよびコンテンツ用のサブパッケージが埋め込まれるので、埋め込まれるターゲットのパスをコンテナプロジェクトの filter.xml に追加して、埋め込まれたパッケージがビルド時にコンテナパッケージに確実に組み込まれるようにする必要があります。
デプロイするサブパッケージを格納した第 2 レベルのフォルダーに対応する <filter root="/apps/<my-app>-packages"/> エントリを追加するだけです。
完全なスニペットについては、この後の POM XML スニペット の節を参照してください。

サードパーティパッケージの埋め込み

All packages must be available via the Adobe's public Maven artifact repository or an accessible public, referenceable 3rd party Maven artifact repository.
アドビが公開している Maven アーティファクトリポジトリ ​にサードパーティパッケージがある場合、Adobe Cloud Manager でアーティファクトを解決するための設定は、それ以上必要ありません。
公開されているサードパーティ Maven アーティファクトリポジトリ ​にサードパーティパッケージがある場合は、このリポジトリをプロジェクトの pom.xml に登録し、 上記 の方法に従って埋め込む必要があります。サードパーティのアプリケーション/コネクタにコードパッケージとコンテンツパッケージの両方が必要な場合は、それぞれをコンテナ( all )パッケージ内の正しい場所に埋め込む必要があります。
Maven の依存関係を追加する場合は、Maven の標準的な手法に従います。サードパーティアーティファクト(コードパッケージとコンテンツパッケージ)の埋め込みについては、 上記 のとおりです。
完全なスニペットについては、この後の POM XML スニペット の節を参照してください。

ui.apps パッケージと ui.content パッケージの依存関係

パッケージの適切なインストールを確実におこなうために、パッケージ間の依存関係を設定することをお勧めします。
The general rule is packages containing mutable content ( ui.content ) should depend on the immutable code ( ui.apps ) that supports the rendering and use of the mutable content.
この一般規則の顕著な例外は、不変コードパッケージ( ui.apps またはその他)がOSGiバンドル みを含む場合です。 依存関係がある場合、AEMパッケージで依存関係を宣言する必要はありません。 これは、OSGiバンドル を含む不変コードパッケージ のみ、OSGiバンドルが登録されていないため、AEM Package Managerには登録されず、依存関係に依存するAEMパッケージの依存関係が満たされず、インストールに失敗するためです。
完全なスニペットについては、この後の POM XML スニペット の節を参照してください。
コンテンツパッケージの依存関係の一般的なパターンは以下のとおりです。

デプロイメントパッケージ間のシンプルな依存関係

シンプルな依存関係は、可変コンテンツパッケージ ui.content が不変コードパッケージ ui.apps に依存するように設定する場合です。
  • all には依存関係がありません
    • ui.apps には依存関係がありません
    • ui.content ui.apps に依存しています

デプロイメントパッケージ間の複雑な依存関係

複雑なデプロイメントは、シンプルなケースをさらに拡張したもので、対応する可変コンテンツパッケージと不変コードパッケージの間に依存関係を設定します。必要に応じて、不変コードパッケージ間にも依存関係を設定できます。
  • all には依存関係がありません
    • ui.apps.common には依存関係がありません
    • ui.apps.site-a ui.apps.common に依存しています
    • ui.content.site-a ui.apps.site-a に依存しています
    • ui.apps.site-b ui.apps.common に依存しています
    • ui.content.site-b ui.apps.site-b に依存しています

ローカル開発とデプロイメント

この記事で概要を説明しているプロジェクト構造および編成は、ローカル開発 AEM インスタンスに​ 完全に対応 ​しています。

POM XML スニペット

上記の推奨事項に合わせて Maven プロジェクトに追加できる Maven pom.xml 設定スニペットを以下に示します。

パッケージタイプ

サブパッケージとしてデプロイされるコードパッケージとコンテンツパッケージでは、パッケージに含まれる内容に応じて、 アプリケーション ​か​ コンテンツ ​のパッケージタイプを宣言する必要があります。

コンテナパッケージタイプ

コンテナ all/pom.xml プロジェクトでは <packageType> を宣言​ しません

コード(不変)パッケージタイプ

コードパッケージでは、 packageType application に設定する必要があります。
ui.apps/pom.xml では、プラグイン宣言 filevault-package-maven-plugin のビルド設定ディレクティブ <packageType>application</packageType> でパッケージタイプを宣言します。
...
<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>
    ...

コンテンツ(可変)パッケージタイプ

コンテンツパッケージでは、 packageType content に設定する必要があります。
ui.content/pom.xml では、プラグイン宣言 filevault-package-maven-plugin のビルド設定ディレクティブ <packageType>content</packageType> でパッケージタイプを宣言します。
...
<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>
    ...

Adobe Cloud Manager によるデプロイメント用のパッケージのマーク

コンテナ( all )プロジェクトを​ 除き 、パッケージを生成するすべてのプロジェクトでは、プラグイン宣言 filevault-package-maven-plugin <properties> 設定に <cloudManagerTarget>none</cloudManagerTarget> を追加して、プロジェクトが Adobe Cloud Manager でデプロイ​ されない ​ようにします。The container ( all ) package should be the singular package deployed via Cloud Manager, which in turn embeds all required code and content packages.
...
<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 スクリプトを含む Repo Init スクリプトは、 scripts プロパティを介して RepositoryInitializer OSGi ファクトリ設定で定義されます。OSGi 設定内で定義されるこれらのスクリプトは、通常の ../config.<runmode> フォルダーセマンティクスを使用して、実行モードで簡単にスコープできることに注意してください。
スクリプトは通常複数行の宣言なので、XML ベースの sling:OsgiConfig 形式よりも .config ファイルで定義するほうが容易なことに注意してください。
/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
"]

scripts OSGi プロパティには、 Apache Sling の Repo Init 言語 で定義されたディレクティブが含まれます。

リポジトリ構造パッケージ

ui.apps/pom.xml と、コードパッケージ( <packageType>application</packageType> )を宣言する他の任意の pom.xml で、次のリポジトリ構造パッケージ設定を FileVault Maven プラグインに追加します。 プロジェクト用に独自のリポジトリ構造パッケージを作成 することができます。
...
<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>
    ...

コンテナパッケージへのサブパッケージの埋め込み

all/pom.xml で、次の <embeddeds> ディレクティブをプラグイン宣言 filevault-package-maven-plugin に追加します。なお、 <subPackages> 設定は​ 使用しない ​でください。この設定では、 /apps/my-app-packages/<application|content>/install(.author|.publish)? ではなく /etc/packages 内のサブパッケージを組み込むことになるからです。
...
<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>
...

コンテナパッケージのフィルター定義

all プロジェクトの filter.xml all/src/main/content/jcr_root/META-INF/vault/definition/filter.xml )に、デプロイするサブパッケージを格納したすべての -packages フォルダーを​ 含めます
<filter root="/apps/my-app-packages"/>

埋め込まれるターゲットで複数の /apps/*-packages が使用されている場合は、それらをすべてここに列挙する必要があります。

サードパーティ Maven リポジトリ

Mavenリポジトリをさらに追加すると、追加のMavenリポジトリが依存関係をチェックするので、MavenリポジトリがMavenビルド時間を延長する場合があります。
公開されているサードパーティ Maven リポジトリで必要なものがあれば、それらのリポジトリディレクティブをリアクタープロジェクトの pom.xml に追加します。完全な <repository> 設定は、サードパーティリポジトリプロバイダから入手できるはずです。
<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>

ui.apps パッケージと ui.content パッケージの依存関係

ui.content/pom.xml で、次の <dependencies> ディレクティブをプラグイン宣言 filevault-package-maven-plugin に追加します。
...
<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>
...

コンテナプロジェクトのターゲットフォルダーのクリーンアップ

Maven ビルドの前にターゲットディレクトリをクリーンアップする maven-clean-plugin プラグインを all/pom.xml に追加します。
<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>