Flex Gateway新着情報
Governance新着情報
Monitoring API ManagerMule 4 のクラスローディングスキーマは、ランタイム、アプリケーション、モジュールを互いに分離します。それぞれは (クラスではなく) パッケージを指定し、API の一部としてエクスポートして、これらのパッケージを可視化します。
Mule 3 のクラスローディングの問題:
モジュールが互いに分離されなかった。
モジュールが Mule Runtime から分離されなかった。
モジュールが Mule アプリケーションから分離されなかった。
Mule 3 では、一部のライブラリを使用するモジュールが、同じライブラリの別のバージョンを使用する他のモジュール、アプリケーション、またはランタイムと競合することがありました。この競合によってクラスローディングの問題が発生し、ClassNotFoundException
や NoSuchMethodException
など、トラブルシューティングの困難な混乱を招くエラーメッセージが表示されることがありました。
クラスローディングは、クラスではなくパッケージによって自動的に絞り込まれるため、どのパッケージをエクスポートして Mule アプリケーションに対して可視化するかを、モジュールが指定する必要があります。
エクスポートするパッケージを判断するために、SDK は各設定、接続、コンポーネントの戻り値と入力種別を調べてそれらのパッケージを取得します。そのため、エクスポートしないクラスがエクスポートされるパッケージから除外されていることを確認する必要があります。エクスポートされるクラスは、エクスポートしないクラスとパッケージを共有していない必要があります。
次のパッケージ階層をお勧めします (MuleSoft モジュールで内部的に使用)。
org.mule.module \--> .api.* \--> .internal.*
.api.*
には、Mule アプリケーションによってエクスポートされ表示されるすべてのクラス (戻り値のデータ型、サブタイプ、入力種別、接続インターフェース) が含まれる。
.internal.*
には、モジュールの特定の動作に使用されるすべてのクラス (アノテーション付きのクラス、Connection
および Operation
実装と内部クラス) が含まれる。
MuleSoft では、エクスポートされたすべてのクラスがモジュールに属することを推奨しています。
ライブラリの衝突により、モジュールと他のモジュール、アプリケーション連動関係、さらにはランタイムとの互換性がなくなるという問題を回避するため、以下が強く推奨されます。
モジュールが使用しているライブラリに属するクラスからは絶対にオブジェクトを戻したり受け取ったりしないこと。
次のセクションのシナリオを検討してください。
このシナリオでは、操作が非常に異なる 2 つのモジュールを使用します。どちらも同じライブラリ (GSON) を使用して JSON を解析し、JsonObject
クラスのインスタンスを返します。片方は GSON バージョン 1.1
、他方は GSON バージョン 2.3
を使用します。JsonObject
クラスは、両方のバージョンとして同じパッケージに含まれていますが、各バージョンの実装が異なるため、クラス間の互換性がなくなります。
この例では、JsonObject
クラスを操作の戻り値のデータ型として公開しています。
public JsonObject getEmployee(@Connection EmployeesServiceConnection connection, String id) {
return new JsonObject(connection.getById(id));
}
public JsonObject getAllProducts(@Connection ProductsServiceConnection connection) {
return new JsonObject(connection.getProdsJson());
}
Mule アプリケーションをデプロイしてから、同じパッケージをエクスポートする 2 つのモジュールを使用しようとすると、2 つのモジュールが同じパッケージをエクスポートできないため、Mule はエラーとなります。
前述の例を少し変えて、操作が GSON パッケージをエクスポートしないものとします。その代わりに java.lang.Object
を戻します。
public Object getEmployee() {
// Here JsonObject is from GSON 1.1
return new JsonObject();
}
public Object getAllProducts() {
// Here JsonObject is from GSON 2.3
return new JsonObject();
}
アプリケーションで両方のモジュールを使用すると、両方のクラスの完全修飾名がまったく同じであるため、2 つのバージョンのうち片方だけが読み込まれます。完全修飾名の衝突によって、パッケージの読み込まれなかったほうのバージョンを必要とするモジュールは、異なる動作を起こして ClassCastException
や NoSuchMethodException
などのエラーが発生しやすくなります。