JBoss AS 7のclassloaderメカニズム

8761 ワード

JBoss AS 7のclassloaderメカニズム
用語
Deployment
AS 7に配備されているear、warなどはdeploymentと呼ばれています.
概要
JBoss AS 7(以下AS 7と略す)のclass loaderメカニズムはJBoss以前のバージョンと大きく異なる.AS 7のclassloadingはJBoss Modulesプロジェクトで実現された.従来の扁平化された両親の依頼メカニズムとは異なり,AS 7のclassloadingはmoduleに基づいており,1つのmoduleが別のmoduleを「見る」ためには依存関係を明示的に定義しなければならない.AS 7に配備されたear,warもmoduleと見なされ,earまたはwarがAS 7に付随するjarへの依存を明示的に定義していない場合,コンテナのjarは「見えない」.
deploymentのmodule名
  • warのmodule nameは:deployment.myarchive.war
  • earのwarのmodule nameは:deployment.myear.ear.mywar.war

  • 自動依存
    earにAS 7の各JEE仕様のjarの依存を明示的に定義する必要がある場合は、明らかに必要ありません.したがって、AS 7はearを配備する際に、earが手動で指定することなくdeploymentに依存を自動的に追加します.例えばearにはpersistenceが含まれている.xmlでは、AS 7はJPA moduleの依存を自動的に追加します.たとえばearに@Statelessのejbが含まれている場合、AS 7はejb moduleの依存を自動的に追加します.
    earがAS 7をexcludeして追加の依存を開始したい場合は、META-INF/jboss-deployment-structure.xmlにexcludeを追加します.
    class loadingの順序
    従来のJBossバージョンではearにxx-version 1が含まれていた.JArと同時に、容器にもxx-version 2が存在する.jarの場合、異なるバージョンのjarが共存できないという問題が発生します.この問題を解決するために、AS 7ではclass loadingの順序が定義されている.
    class loadingの優先度は高いものから低いものまで:
  • AS 7自動追加依存
  • jboss-deployment-structure.xmlで定義された
  • WEB-INF/classesまたはWEB-INF/lib
  • deployment間の依存、例えばear中のwaru依存ear中のejb
  • warのclass loading
    1つのwarはmoduleと見なされるため、warのWEB-INF/libはWEB-INF/classesと平等であり、両者のclassは同じclassloaderにロードされる
    ear classloading
    earの構造を次のように仮定します.
    1 2 3 4 5 6 7 
    myapp.ear  |  |--- web.war  |  |--- ejb1.jar  |  |--- ejb2.jar

    AS 7のデフォルト動作は:
  • web.warはejb 1が見えます.JArとejb 2.jar
  • ejb1.JArとejb 2.jarは互いに
  • が見えます
    もしそうならxmlのear-subdeployments-isolatedをtrueとするとweb.war、ejb1.jar、ejb2.jarは互いに見えなくなった.
    1 2 3 
    <subsystem xmlns="urn:jboss:domain:ee:1.0" >  <ear-subdeployments-isolated>false</ear-subdeployments-isolated> </subsystem>

    global modules
    ee subsystemでは、deploymentに依存するすべてのmoduleを設定できます.たとえば、次のようにします.
    1 2 3 4 5 
    <subsystem xmlns="urn:jboss:domain:ee:1.0" >  <global-modules>  <module name="org.javassist" slot="main" />  </global-modules> </subsystem>

    jboss-deployment-structure.xmlファイル
    jboss-deployment-structure.xmlはJBoss特有のファイルで、class loadingを細かく制御するために使用され、META-INFフォルダに入れるべきです.jboss-deployment-structure.xmlでは、次のことができます.
  • exclude掉AS 7自動添加依存
  • 既存moduleへの依存
  • を明示的に追加
  • 追加module
  • を定義する
  • EAR deployments isolated挙動を変更する
  • 例は次のとおりです(詳細はxml schemaを参照).
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 
    <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">  <!-- Make sub deployments isolated by default, so they cannot see each others classes without a Class-Path entry -->  <ear-subdeployments-isolated>true</ear-subdeployments-isolated>  <!-- This corresponds to the top level deployment. For a war this is the war's module, for an ear -->  <!-- This is the top level ear module, which contains all the classes in the EAR's lib folder -->  <deployment>  <!-- exclude-subsystem prevents a subsystems deployment unit processors running on a deployment -->  <!-- which gives basically the same effect as removing the subsystem, but it only affects single deployment -->  <exclude-subsystems>  <subsystem name="resteasy" />  </exclude-subsystems>  <!-- Exclusions allow you to prevent the server from automatically adding some dependencies -->  <exclusions>  <module name="org.javassist" />  </exclusions>  <!-- This allows you to define additional dependencies, it is the same as using the Dependencies: manifest attribute -->  <dependencies>  <module name="deployment.javassist.proxy" />  <module name="deployment.myjavassist" />  <!-- Import META-INF/services for ServiceLoader impls as well -->  <module name="myservicemodule" services="import"/>  </dependencies>  <!-- These add additional classes to the module. In this case it is the same as including the jar in the EAR's lib directory -->  <resources>  <resource-root path="my-library.jar" />  </resources>  </deployment>  <sub-deployment name="myapp.war">  <!-- This corresponds to the module for a web deployment -->  <!-- it can use all the same tags as the <deployment> entry above -->  <dependencies>  <!-- Adds a dependency on a ejb jar. This could also be done with a Class-Path entry -->  <module name="deployment.myear.ear.myejbjar.jar" />  </dependencies>  <!-- Set's local resources to have the lowest priority -->  <!-- If the same class is both in the sub deployment and in another sub deployment that -->  <!-- is visible to the war, then the Class from the other deployment will be loaded, -->  <!-- rather than the class actually packaged in the war. -->  <!-- This can be used to resolve ClassCastExceptions if the same class is in multiple sub deployments-->  <local-last value="true" />  </sub-deployment>  <!-- Now we are going to define two additional modules -->  <!-- This one is a different version of javassist that we have packaged -->  <module name="deployment.myjavassist" >  <resources>  <resource-root path="javassist.jar" >  <!-- We want to use the servers version of javassist.util.proxy.* so we filter it out-->  <filter>  <exclude path="javassist/util/proxy" />  </filter>  </resource-root>  </resources>  </module>  <!-- This is a module that re-exports the containers version of javassist.util.proxy -->  <!-- This means that there is only one version of the Proxy classes defined -->  <module name="deployment.javassist.proxy" >  <dependencies>  <module name="org.javassist" >  <imports>  <include path="javassist/util/proxy" />  <exclude path="/**" />  </imports>  </module>  </dependencies>  </module> </jboss-deployment-structure>

    Reference:
  • https://docs.jboss.org/author/display/AS72/Class+Loading+in+AS7