術語
Deployment
部署在AS7中的ear、war等都被稱作為deployment。
簡介
JBoss AS7(以下簡稱AS7)的class loader機制與JBoss之前的版本有很大的不同。AS7的classloading是在JBoss Modules項目中實現的。與之前的扁平化的雙親委托機制不同,AS7的classloading是基于module的,一個module如果想要“看見”另一個module,必須要顯式地定義依賴關系。部署在AS7中ear、war也被看作是module,如果ear或者war沒有顯式地定義對AS7自帶的jar的依賴的話,那么是“看不見”容器的jar的。
deployment的module名稱
- war的module name為: deployment.myarchive.war
- ear中的war的module name為: deployment.myear.ear.mywar.war
自動依賴
如果讓ear必須顯式地定義AS7每一個JEE規范的jar的依賴的話,顯然是沒有必要的,因此AS7在部署一個ear時,會自動為deployment添加上一些依賴,而不用ear手工指定。比如ear中包含persistence.xml,那么AS7會自動為其添加JPA module的依賴,再比如ear中包含@Stateless的ejb時,AS7會自動為其添加ejb module的依賴。
如果ear想exclude掉AS7啟動添加的依賴,可以在META-INF/jboss-deployment-structure.xml中添加exclude。
class loading的順序
在以往的JBoss版本中,當ear中包含了xx-version1.jar的同時,容器也存在xx-version2.jar的話,就會出問題,也就是不同版本的jar不能共存。為了解決這個問題,AS7中定義了class loading的順序。
class loading的優先級從高到低:
- AS7自動添加的依賴
- jboss-deployment-structure.xml中定義的
- WEB-INF/classes 或者 WEB-INF/lib
- deployment之間的依賴,比如ear中的waru依賴ear中的ejb
war的class loading
由于一個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
|
AS7默認行為是:
- web.war能看見ejb1.jar與ejb2.jar
- ejb1.jar與ejb2.jar能互相看見
如果standalone.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掉AS7自動添加的依賴
- 顯式地添加對現有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: