クラスローディングの分離

Mule Runtime Engine は、Java やその他多くのサードパーティライブラリを使用して開発されています。Mule アプリケーションには、Java ライブラリ、特に Mule を拡張してインテグレーション機能を提供するモジュール (HTTP 用 Anypoint Connector や XML モジュールなど) を含めることもできます。これらの拡張モジュールに Java (JAR) ライブラリを含めることもできます。

JVM のデフォルトのクラスローディングメカニズムにより、同じ JAR ファイルのバージョンが競合する可能性があります。Mule では、各アーティファクト (ランタイム、Mule アプリケーション、Mule 拡張) は単独で開発およびリリースされますが、これらのアーティファクトの JAR はすべて同じ場所にあります。たとえば、Mule アプリケーションで Apache Commons Collections 2.1 を使用しているとします。使用する拡張には Apache Commons Collections 3.1 が必要な場合、Commons Collections 2.1 と Commons Collections 3.1 のリソースが競合するため、アプリケーションは期待どおりに機能しない可能性があります。

  • Mule 3 での解決方法

    異なるアプリケーション間の競合の問題を解決するため、Mule 3 はクラスローダーの階層組織を使用していました。Mule アプリケーションは、その拡張、その中にバンドルされているライブラリ、そのランタイムライブラリを参照できますが、他のアプリケーションのライブラリにはアクセスできません。

    Mule 3 では、異なる拡張のライブラリ間の競合、拡張とアプリケーションのライブラリ間の競合、アプリケーションとランタイムのライブラリ間の競合など、その他の潜在的競合が残っていました。

  • Mule 4 での解決方法

    Mule 4 では、クラスローディングメカニズムで上述の Mule 3 のすべての問題が対応されています。

API 定義

Mule Runtime Engine とアーティファクト (アプリケーション、ドメイン、ポリシー、拡張) には、各アーティファクトのコントラクトを指定し、他のアーティファクトへのアーティファクトコンテンツの公開を制限する明確な API 定義が必要です。

各アーティファクトの明確な API 定義では、クラスとライブラリのスコープを制限する方法が提供されます。これにより、すべて共有することを防ぐクラスローダーを作成できます。

Mule 4 API

Mule 3 は、そのライブラリ内にバンドルされているすべてのクラスを公開します。この公開により、ランタイムの変更がカスタム Java クラスに影響する可能性があるため、Mule バージョンを別のランタイムにアップグレードするときに問題が発生していました。

Mule 4 では、Mule の拡張を容易にする明確に定義された API が備えられ、適切な拡張ポイントが明確化されています。

  • コア API: Mule メッセージ。

  • 拡張 API: Mule Runtime 4 を拡張するモジュール、メッセージプロセッサー、変換、その他の要素。

  • Tooling API: すべての DataSense メタデータと伝播が Mule Runtime 4 に含まれるようになりました。この API は Runtime Manager エージェントにバンドルされています。

アーティファクト API

アーティファクト (アプリケーション、ドメイン、ポリシー、または拡張) を作成する場合、そのモジュールの公開 API を宣言する必要があります。

公開 API の定義方法

アーティファクトのリソースをエクスポートするには、​「リソースのエクスポート」​を参照してください。

考慮事項

  • エクスポートされていないリソースとクラスは他のアーティファクトから参照できない。

  • アーティファクトから最小限必要なパッケージとリソースのセットを公開する。

  • 必要でない限り、サードパーティのライブラリはエクスポートしない。

  • Guava、Apache common-collections などのサードパーティの共通ライブラリは絶対公開しない。公開すると、他のアーティファクトと競合します。

  • 理想的には、アーティファクト (または JDK) のクラスのみを公開する。

Semver

Mule 4 ので提供されるすべての API は セマンティックバージョニング 2.0.0​ に従います。

API 制限

すべての公開 API には制限が適用される可能性があります。これらの制限により、API の使用方法が制限されます。詳細は、 「API annotations」モジュール​を参照してください。

API に定義されている API 制限により、異なるバージョン間で発生する可能性がある API の変更に対する柔軟性が向上するため、それらの制限を考慮する必要があります。

クラスローディング分離メカニズム

API が明確に定義されたら、アーティファクトの内部クラスへのアクセスを防ぎ、外部からは公開 API にのみアクセス可能にすることができます。API を保護するため、Mule 4 はカスタムクラスローディングメカニズムを使用しています。

次の拡張ファイル構造を考えてみます。

com/example/extension/api/MyClass.class
com/example/extension/internal/Util.class
transformations/customer-to-user.dwl
license.txt
META-INF/mule-artifact/mule-artifact.json

また、この拡張には次の ​mule-artifact.json​ 記述子ファイルがあります。

{
    "name": "my-test-extension",
    "minMuleVersion": "4.0.0",
    "classLoaderModelLoaderDescriptor": {
        "id": "mule",
        "attributes": {
            "exportedResources": [
                "transformations/customer-to-user.dwl"
            ],
            "exportedPackages": [
                "com/example/extension/api"
            ]
        }
    }
}

次の図は ​mule-artifact.json​ によってエクスポートされたリソースがアプリケーション内に適用される方法を示しています。

単純なクラスローディング図
Artifact Class Loader (アーティファクトクラスローダー)

拡張に含まれる JAR ファイルを指す通常の Java クラスローダー。このクラスローダーは、拡張のすべてのファイルとクラスを読み込みます。

Artifact Filtering Class Loader (アーティファクト絞り込みクラスローダー)

アーティファクトクラスローダー上に作成されたラッパー。外部アーティファクト (アプリケーションまたは他のプラグイン) の拡張コードへのアクセスを制限します。​mule-artifact.json​ 記述子のコンテンツを使用して、何が公開されるかを判断します。

Extension Code (拡張コード)

Mule 拡張コード。アーティファクトクラスローダー (制限なし) を使用し、プラグイン自体のリソースの検出のみが可能です。

Application Code (アプリケーションコード)

Mule アプリケーションコード。拡張のアーティファクト絞り込みクラスローダーを使用して、制限されたコードやリソースにアプリケーションがアクセスすることを防ぎます。

コネクタへの連動関係の追加

アプリケーションのコネクタがプロジェクト内の連動関係にアクセスする必要がある場合、連動関係を設定してコネクタのクラスローダーから参照できるようにします。これには 2 つの方法があります。

共有ライブラリ

アプリケーションの ​pom.xml​ ファイル内で宣言されたすべての連動関係 (JAR ファイルなど) は、アプリケーションのクラスローダーからは参照できますが、アプリケーション内で使用される各コネクタのクラスローダーからは参照できません。Mule Runtime Engine のクラスローディングメカニズムは、各コネクタを分離することで、他のコネクタのクラスにアクセスすることを防ぎます。コネクタのクラスローダーがアプリケーション連動関係にアクセスする必要がある場合は、この連動関係を共有ライブラリとして宣言します。

Java 用 Anypoint Connector を使用するアプリケーションについて考えてみます。コネクタはアプリケーションの ​pom.xml​ ファイル内で宣言された JAR 連動関係に含まれるクラスを使用する必要があります。ただし、コネクタのクラスローダーがそのクラスを見つけることができないため、それができません。コネクタがこのクラスを参照できるようにするには、そのクラスを含む連動関係を共有ライブラリとして、アプリケーションの ​pom.xml​ ファイルの Mule Maven プラグイン設定内で宣言する必要があります。

Anypoint Studio または Flow Designer を使用して、外部ライブラリを使用するコネクタを設定する場合は、連動関係は自動的に共有ライブラリとして追加されます。たとえば、データベース用 Anypoint Connector をアプリケーションに追加してから Anypoint Studio を使用して接続ドライバーを設定すると、ドライバーは自動的にプロジェクトの ​pom.xml​ ファイルに共有ライブラリとして追加されます。

設定の手順は、​「共有ライブラリの設定」​を参照してください。

共有ライブラリは、アプリケーション内のすべてのコネクタから参照可能です。共有ライブラリに含まれているのと同じクラスの別のバージョンが他のコネクタやその連動関係内にある場合は、共有ライブラリを設定すると問題が発生することがあります。

追加プラグイン連動関係

共有ライブラリを設定してアプリケーションの連動関係をアプリケーション内のすべてのコネクタから参照可能にする代わりに、追加プラグイン連動関係を設定して特定のコネクタのクラスパスを強化できます。この設定を使用すると、コネクタの ​pom.xml​ ファイルで新しい連動関係が宣言されたかのように、連動関係を効果的にコネクタに追加できます。

追加プラグイン連動関係を設定すると、その連動関係は設定されたコネクタでのみ使用できるようになり、アプリケーションの連動関係として宣言する必要はありません。

追加プラグイン連動関係を設定するときには、連動関係のバージョンを指定する必要があります。

設定の手順は、​「追加プラグイン連動関係の設定」​を参照してください。