9.2. ClassLoading

ClassLoader 抽象化を直接使用する代わりに、ClassLoader 依存関係の宣言を含む ClassLoading モジュールを作成できます。依存関係が指定されたら、 ClassLoaderPolicyが構築され、適切に一緒に接続されます。
ClassLoaders が実際に存在する前に ClassLoaders を定義することを支援するために、抽象化には ClassLoadingMetaData モデルが含まれます。
ClassLoadingMetaData は新しい JBoss EAP プロファイルサービス内で Managed Object として公開できます。これにより、システム管理者は実装の詳細よりも抽象的なポリシーの詳細を扱うことができるようになります。

例9.4 Managed Object としての ClassLoadingMetaData Exposed

public class ClassLoadingMetaData extends NameAndVersionSupport {
    /** The serialVersionUID */
    private static final long serialVersionUID = -2782951093046585620L;

    /** The classloading domain */
    private String domain;

    /** The parent domain */
    private String parentDomain;

    /** Whether to make a subdeployment classloader a top-level classloader */
    private boolean topLevelClassLoader = false;

    /** Whether to enforce j2se classloading compliance */
    private boolean j2seClassLoadingCompliance = true;

    /** Whether we are cacheable */
    private boolean cacheable = true;

    /** Whether we are blacklistable */
    private boolean blackListable = true;

    /** Whether to export all */
    private ExportAll exportAll;

    /** Whether to import all */
    private boolean importAll;

    /** The included packages */
    private String includedPackages;

    /** The excluded packages */
    private String excludedPackages;

    /** The excluded for export */
    private String excludedExportPackages;

    /** The included packages */
    private ClassFilter included;

    /** The excluded packages */
    private ClassFilter excluded;

    /** The excluded for export */
    private ClassFilter excludedExport;

    /** The requirements */
    private RequirementsMetaData requirements = new RequirementsMetaData();

    /** The capabilities */
    private CapabilitiesMetaData capabilities = new CapabilitiesMetaData();

    ... setters & getters
			
			
			
			

例9.5「XML で定義されたクラスローディング API」例9.6「Java で定義されたクラスローディング API」 は、それぞれ XML と Java で定義されたクラスローディング API を示しています。

例9.5 XML で定義されたクラスローディング API

<classloading xmlns="urn:jboss:classloading:1.0"
	      name="ptd-jsf-1.0.war"
	      domain="ptd-jsf-1.0.war"
	      parent-domain="ptd-ear-1.0.ear"
	      export-all="NON_EMPTY"
	      import-all="true"
	      parent-first="true"/>
			
			
			
			

例9.6 Java で定義されたクラスローディング API

ClassLoadingMetaData clmd = new ClassLoadingMetaData();
if (name != null)
    clmd.setDomain(name + "_Domain");
clmd.setParentDomain(parentDomain);
clmd.setImportAll(true);
clmd.setExportAll(ExportAll.NON_EMPTY);
clmd.setVersion(Version.DEFAULT_VERSION);
			
			
			
			

展開への ClassLoadingMetaData の追加は、プログラムを使用するか、jboss-classloading.xml で宣言することにより行えます。

例9.7 jboss-classloading.xml を使用した ClassLoadingMetaData の追加

<classloading xmlns="urn:jboss:classloading:1.0"
	      domain="DefaultDomain"
	      top-level-classloader="true"
	      export-all="NON_EMPTY"
	      import-all="true">
</classloading>
DefaultDomain は、独自のドメインを定義しないすべてのアプリケーション間で共有されます。

例9.8 一般的なドメインレベルの分離

<classloading xmlns="urn:jboss:classloading:1.0"
	      domain="IsolatedDomain"
	      export-all="NON_EMPTY"
	      import-all="true">
</classloading>

例9.9 特定の親による分離

<classloading xmlns="urn:jboss:classloading:1.0"
	      domain="IsolatedWithParentDomain"
	      parent-domain="DefaultDomain"
	      export-all="NON_EMPTY"
	      import-all="true">
</classloading>

			
			
			
			

例9.10 j2seClassLoadingCompliance に準拠しない

<classloading xmlns="urn:jboss:classloading:1.0"
	      parent-first="false">
</classloading>
			
			
			
			

.war 展開はデフォルトでこのメソッドを使用します。デフォルトの parent-first ルックアップを行う代わりに最初に独自のリソースをチェックします。

例9.11 一般的な OSGi 実装

<classloading xmlns="urn:jboss:classloading:1.0">
  <requirements>
    <package name="org.jboss.dependency.spi"/>
  </requirements>
  <capabilities>
    <package name="org.jboss.cache.api"/>
    <package name="org.jboss.kernel.spi"/>
  </capabilities>
</classloading>

例9.12 粒度が細かいパッケージではなくモジュールとライブラリ全体のインポートとエクスポート

<classloading xmlns="urn:jboss:classloading:1.0">
  <requirements>
    <module name="jboss-reflect.jar"/>
  </requirements>
  <capabilities>
    <module name="jboss-cache.jar"/>
  </capabilities>
</classloading>
			
			
			
			

<classloading xmlns="urn:jboss:classloading:1.0">
  <requirements>
    <package name="si.acme.foobar"/>
    <module name="jboss-reflect.jar"/>
  </requirements>
  <capabilities>
    <package name="org.alesj.cl"/>
    <module name="jboss-cache.jar"/>
  </capabilities>
</classloading>
			
			
			
			

また、パッケージとモジュールを使用して要件と機能のタイプを組み合わせることもできます。
クラスローディングサブプロジェクトは非常に小さい resource-visitor-pattern 実装を使用します。
ClassLoader プロジェクトでは、展開とクラスローディング間の接続が、フィルタリングなどのビジターパターンに制限を適切に適用するために必要なすべての情報を保持する Module クラスを使用して行われます。

例9.13 ResourceVisitor インターフェースと ResourceContext インターフェース

public interface ResourceVisitor {
    ResourceFilter getFilter();

    void visit(ResourceContext resource);
}

public interface ResourceContext {
    URL getUrl();

    ClassLoader getClassLoader();

    String getResourceName();

    String getClassName();

    boolean isClass();

    Class<?> loadClass();

    InputStream getInputStream() throws IOException;

    byte[] getBytes() throws IOException;
}
			
			
			
			

モジュールを使用するには、ResourceVisitor インスタンスをインスタンス化し、Module::visit メソッドに渡します。この機能は、展開のアノテーション使用をインデックス化するために展開フレームワークで使用されます。