2

私は苦労している質問があります。問題は、Googleで正確に何を検索すればよいかさえわからないことです。そのため、SOで簡単な説明を求めています。

A、B、C の 3 つのプロジェクトがあるとします。A は B と C の両方の依存関係です。B と C は、たとえば、Glassfish にデプロイできる Web サービスです。Aには、静的フィールドを持つクラスがあります。たとえば、 int. プロジェクト B をビルドするとき、 のstatic int値は 3 です。次に、プロジェクト C をビルドしますが、 の値static intを 4 に変更します。

問題は、B と C の両方を Glassfish にデプロイする場合、これらのアプリケーションは、static int環境ごとに異なる値 (B の環境では 3、C の環境では 4) を持つ別々の「環境」で実行されますか、それとも 1 つだけですか? static int?

LE: B と C は両方とも同じ Glassfish ドメインにデプロイされています。Glassfish のバージョンは 3.1.1 です。

4

2 に答える 2

2
The problem is that I do not even know what exactly I should search for on google, so that's why I am asking for a short explanation here on SO.

検索したいのは「Classloader」です。このタイプのオブジェクトは、Java クラスのロードを担当します。JVM によってロードされる各クラスは、その完全修飾名とそれをロードしたクラスローダーのインスタンスの両方によって識別されます。これは、単一の JVM で、正確に「com.example.Test」という名前のいくつかのクラスを持つことができ、それぞれが異なるクラスローダーによってロードされ、それぞれに独自の静的フィールドがあることを意味します。さらに、これらのクラスは実行時に異なると見なされます。あるクラスローダから「com.example.Test」を別のクラスローダの「com.example.Test」にキャストすると、ClassCastException が発生します。

多数の共通クラス (java.util.List など) が複数回ロードされる状況を回避するために、通常、クラスローダーはクリーンな階層に保持されます。各クラスローダは、その「親」、つまり「より一般的なクラス」のロードを担当するクラスローダを認識しています。「com.example.OtherTest」のように、(通常は「名前で」行われる) クラスをロードしようとすると、現在のクラスローダーは、そのクラスをロードできるかどうかをその親に尋ねようとします (そして、親はその親に尋ねます) 、 等々)。このようにして、各クラスは、それをロードできる最も一般的なクラスローダによってロードされます (java.lang.String は、他のクラスローダが別のバージョンを利用できる場合でも、標準のブートストラップ クラスローダによって常にロードされます)。

war をデプロイすると、glassfish はそれ用に別のクラスローダーを作成します。クラスローダーは、WEB-INF/lib および WEB-INF/classes からクラスをロードする方法を認識しています。その親 (または少なくとも祖父) は、すべてのアプリケーションに共通のドメイン クラスローダーです。そのため、アプリケーションのクラスローダーがクラスをロードする前に、Glassfish にそれを行うように要求します。

プロセス全体は非常に構成可能であり、共通ライブラリのコピーを 1 つだけ JVM にロードすることができます (たとえば、ライブラリを AFAIR domain1/lib/ext に配置すると、それらはドメイン クラスローダーで利用可能になります。各アプリケーションのクラスローダー; または、JRE の lib/ext フォルダーに配置して、実行するアプリケーションのクラスをロードするメインのクラスローダーで使用できるようにすることもできます)。そのような場合、それらは静的フィールドを共有します。または、war クラスローダーによってライブラリをロードし、すべての静的フィールドをアプリケーションに対して「プライベート」にすることもできます。

于 2012-05-29T12:35:27.183 に答える
2

「A for B」と「A for C」が異なる場合は、B と C の両方に配置を作成し、それぞれに A の独自のコピーを含める必要があります。

最も単純なアプローチは、おそらく A_for_B.jar を囲む B 用の別個の WAR と、A_for_C.jar を囲む C 用の別個の WAR です。

于 2012-05-29T11:57:52.150 に答える