jboss7使用不同的類加載器來隔離子產品。
ecp.ear引用core.ear中的core.jar項目
MANIFEST.MF如下配置時,會發現兩個子產品調用core.jar中的類使用不同的類加載器
Manifest-Version: 1.0
Dependencies: deployment.core.ear.core-ejb.jar
必須要在顯式配置依賴,并且依賴core.ear和core-ejb.jar,core-ejb中的類和ecp-ejb中的類才會使用同一個加載器(core-ejb.jar打包在core.ear中,不能跨過ear直接依賴jar?)
如下:
Manifest-Version: 1.0
Dependencies: deployment.core.ear,deployment.core.ear.core-ejb.jar
================================================轉自網上的資料
從Jboss5遷移到Jboss7
1. Jboss7新特性
1.1 建構在Modular Service Container上,充分地利用了多核處理器的能力,并發、按需啟動服務,啟動速度更快、占用記憶體更小。
1.2 全面相容Java EE6
1.3 支援JDK6/7
1.4 統一的配置和管理
1.5 相容OSGI 4.2,支援OSGI和Java EE元件模型內建。
1.6容易測試:利用Arquillian測試平台—一種內建測試元件模型,更易于測試,改變-編譯-測試的周期更短。
1.7 兩種模式
Standalone模式(使用standalone.bat啟動)相當于以前的3、4、5、6版本。配置檔案、釋出内容等放在standalone目錄下。
Domain模式(使用domain.bat啟動)是Jboss7的一個新特征,可以在一個控制點管理多個伺服器。
1.8 類加載
類加載基于Jboss Module,取代了層次類加載環境,避免了當類存在多個版本時,導緻類加載錯誤。由于類加載是基于子產品的,必須顯示的定義子產品依賴。部署也是子產品化的,如果沒有顯示的定義類依賴則不能通路應用伺服器jar中的類。
2. 遷移步驟
在Jboss7部署項目與在jboss5上有很大差別,最主要原因是由于類的加載模式改變了。Jboss5部署相對簡單,隻需将相應的包部署到lib和deploy目錄即可,類加載器會按層次自動加載,不用配置依賴關系。而jboss7完全不一樣,jboss7是按子產品化加載,不同子產品由不同類加載器加載,其他子產品的jar包,對其是不可見的,這時需要手動配置包之間依賴關系,否則會報ClassNotFoundException等錯誤。另外對于資料源和JNDI的配置也發生了變化,是以把項目從Jboss5往Jboss7遷移時可以大概分為下述3個步驟:
2.1 依賴關系的配置
在Jboss7中,子產品之間的依賴關系分為隐式依賴和顯式依賴。
2.1.1隐式依賴
盡管Jboss7中子產品預設是隔離的,在部署過程中,一些由應用伺服器定義的子產品依賴會自動裝配。例如,如部署一個Java EE應用,将自動添加Java EE API依賴,這也稱為隐式子產品依賴。
2.1.2顯式依賴
對于顯式依賴,必須在MANIFEST.MF檔案的“Dependencies:”或“Class-Path:”項或在Jboss7特有的部署檔案jboss-deployment-structure.xml中顯式定義。對于已有的項目,手動去查找各個子產品之間的依賴關系是費時又費力的,可以通過Tattletale工具來分析,在分析報告的OUTPUT_DIRECTORY/index.html檔案中點選"JBoss A7"則可以得到部分依賴關系,另外的依賴關系可以在“Depends On”中得到。
在Jboss7中類的加載優先級(從高到低):
(1)系統依賴-伺服器自動加載的子產品依賴,包括Java EE api。
(2)使用者依賴-在jboss-deployment-structure.xml(在ear的META-INF内,war的META-INF或WEB-INF内)或Dependencies:項内配置的依賴。
(3)本地資源-釋出目錄下的類檔案,如war包下的WEB-INF/classes或WEB-INF/lib。
(4)部署間依賴-在ear内的其他部署依賴。包括ear lib目錄内的類,或其他ejb包内的類。
在部署時,War包被認為是一個單獨的子產品,WEB-INF/lib和WEB-INF/classes内的類是相同的,都由同一類加載器加載。Ear包是多子產品的部署。這意味着不是ear内的所有類都能通路ear内所有其他類,除非指定明确的依賴。預設情況下,EAR/lib目錄是一個單獨的子產品,每個WAR或EJB jar是一個單獨的子產品。子部署(war和ejb-jar)總是依賴父子產品,可以通路EAR/lib内的類,然而它們彼此間不總是有自動依賴。可以通過修改如下配置控制這個行為:
<subsystem xmlns="urn:jboss:domain:ee:1.0" >
<ear-subdeployments-isolated>false</ear-subdeployments-isolated>
</subsystem>
ear-subdeployments-isolated預設值為false,允許子部署通路其他子部署的類。在一個Ear包中,war可以通路jar包裡的類,jar包之間也可以互相通路,但是jar包不能通路war包中的類,不管ear-subdeployments-isolated的值為true還是false。
2.1.3全局子產品
可以把一些子產品設定為全局子產品,則所有的部署都可以通路該子產品,在做項目遷移時,可以使用這種方法來解決子產品依賴問題。格式如下:
<subsystem xmlns="urn:jboss:domain:ee:1.0"/>
<global-modules>
<module name="org.apache.log4j"/>
</global-modules>
2.2 資料源配置
在Jboss5中,資料源的配置檔案為*-ds.xml檔案,該檔案放在伺服器的deploy目錄下,其相應的JDBC驅動則放在伺服器的lib目錄或應用程式的WEB-INF/lib目錄下。而在Jboss7中這些都不需要,配置檔案為Jboss7_home/standalone/configuration/standalone.xml或者是Jboss7_home/domain/configuration/domaion.xml。可以使用IronJacamar工具把原來的*-ds.xml檔案轉變為Jboss7中所需要的格式。
2.2.1 安裝JDBC驅動
安裝JDBC驅動分為兩種方式:(1)作為一個部署(推薦的做法)(2)作為一個子產品
2.2.1.1 作為一個部署
直接把JDBC驅動作為一個普通的jar包放在deployment目錄下,該JDBC驅動應該是一個相容JDBC4(Jdbc 4相容的driver在jar包内含有META-INF/services/java.sql.Driver檔案,其中指定了驅動類名稱。)的驅動。若JDBC驅動包含不止一個jar包,則應作為一個子產品來部署。
2.2.1.2 作為一個子產品
需要在modules目錄下建立一個目錄結構,其内包含驅動jar包和module.xml檔案。下面以安裝mysql驅動為例,首先在modules目錄下建立com/mysql/main檔案夾,且把mysql驅動和module.xml檔案放在main檔案夾中。module.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.mysql">
<resources>
<resource-root path="mysql-connector-java-5.1.15.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
</dependencies>
</module>
需要注意的是name應與建立的檔案夾同名且module.xml檔案的開頭不能有空格,否則會産生“New missing/unsatisfied dependencies”錯誤。
2.2.2 注冊JDBC驅動
2.2.2.1 作為子產品的JDBC驅動注冊
<datasource jndi-name="java:/YourDatasourceName" pool-name="YourDatasourceName">
<connection-url>jdbc:mysql://localhost:3306/YourApplicationURL</connection-url>
<driver> mysql-connector-java-5.1.15.jar </driver>
<transaction-isolation> TRANSACTION_READ_COMMITTED </transaction-isolation>
<pool>
<min-pool-size>100</min-pool-size>
<max-pool-size>200</max-pool-size>
</pool>
<security>
<user-name> USERID </user-name>
<password> PASSWORD</password>
</security>
<statement>
<prepared-statement-cache-size>100</prepared-statement-cache-size>
<share-prepared-statements/>
</statement>
</datasource>
2.2.2.2 作為部署的JDBC驅動注冊
<datasource jndi-name="java:/MySqlDS" pool-name="MySqlDS" enabled="true" use-java-context="true">
<connection-url>jdbc:mysql://localhost:3306/gg</connection-url>
<driver>mysql</driver>
<pool>
<min-pool-size>20</min-pool-size>
<max-pool-size>20</max-pool-size>
<prefill>true</prefill>
</pool>
<security>
<user-name>root</user-name>
<password>111</password>
</security>
<driver name="mysql" module="com.mysql">
<driver-class>com.mysql.jdbc.Driver</driver-class>
</driver>
</datasources>
2.3 JNDI
2.3.1 JNDI命名規則
jboss7使用了更為嚴格的JNDI命名規則,其基本規則如下:
(1)相對命名如“ExampleDS”或“jdbc/ExampleDS”應該修改為相對于具體環境,如“java:comp/env”,“java:jboss/env”,“java:module/env”等。
(2)絕對命名如“/jdbc/ExampleDS”應該修改為相對命名如“java:jboss/root”。
(3)如“java:/jdbc/ExampleDS”的絕對命名也應如(2)修改。
(4)“java:jboss”命名在整個jboss伺服器中時共享的。
(5)任何以“java:”開頭的命名必須結合“comp”,“module”,“app”,“global”,“jboss”中的一個,否則會報錯。
2.3.2 Local JNDI
name | scope | properties |
java:comp | current component | standard namespaces |
java:module | current module | |
java:app | current application | |
java:global | application server | |
java:jboss | global | jboss7 提供的全局命名 |
java:/ | global | |
java:jboss/exported | global |
如在HelloWorldEar包中有HelloWorldEJB,在HelloWorldEJB中有HelloWorld bean實作了HelloWorldRemote接口,則部署時HelloWorld綁定的JNDI為以下幾個:
java:global/HelloWorldEar/HelloWorldEJB/HelloWorld!com.ejb.HelloWorldRemote
java:app/HelloWorldEJB/HelloWorld!com.ejb.HelloWorldRemote
java:module/HelloWorld!com.ejb.HelloWorldRemote
java:jboss/exported/HelloWorldEar/HelloWorldEJB/HelloWorld!com.ejb.HelloWorldRemote
java:global/HelloWorldEar/HelloWorldEJB/HelloWorld
java:app/HelloWorldEJB/HelloWorld
java:module/HelloWorld
2.3.3 remote JNDI
在jboss5中預設ejb的JNDI名稱為:
本地接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local
遠端接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote
如果ejb隻是在單獨的jar包中,則不需要EAR-FILE-BASE-NAME。而在jboss7中remote ejb的JNDI命名規則如下:
ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>,如果是有狀态bean,則還需加上?stateful。
其中app-name指的是ear包的名稱
module-name指的是其所在的jar包的名稱
distinct-name指的是起的别名
bean-name指的是該bean的名字
fully-qualified-classname-of-the-remote-interface指的是其實作的接口的名字,要加上完整的包名。
2.3.4 綁定全局JNDI
直接修改standalone.xml或者domain.xml檔案,格式如下所示:
<subsystem xmlns="urn:jboss:domain:naming:1.1"/>
<bindings>
<lookup name="AdminEjb/local" lookup="ejb:/admin_ejb/AdminEjb!com.mipt.admin.ifc.AdminIfc"/>
</bindings>
3. 可能會遇到的問題
3.1ejb JNDI
由于jboss7與jboss5JNDI命名方式的差别很大,若在原有項目中大量使用了JNDI,則在遷移時要進行更改或綁定,将是一項龐大的工程。
3.2 配置檔案無法解析
在添加資料源或其他需要修改standalone.xml或domain.xml配置檔案後,重新啟動伺服器會報無法解析配置檔案的錯誤,可以通過jboss-home/bin/jboss-cli.bat來修該配置檔案。以下為添加一個資料源的格式:
[[email protected]:9999 /] /subsystem=datasources:installed-drivers-list
{
"outcome" => "success",
"result" => [{
"driver-name" => "h2",
"deployment-name" => undefined,
"driver-module-name" => "com.h2database.h2",
"module-slot" => "main",
"driver-xa-datasource-class-name" => "org.h2.jdbcx.JdbcDataSource",
"driver-class-name" => "org.h2.Driver",
"driver-major-version" => 1,
"driver-minor-version" => 2,
"jdbc-compliant" => true
}]
3.3 ClassNotFoundException ClassCastException
出現上述問題則是子產品之間缺少依賴關系,導緻找不到相應的類。
總結
在把項目從jboss5遷移到jboss7上時,上述3個步驟能解決大部分的問題。對于日志依賴的配置以及使用了spring、hibernate、EJB2技術的項目遷移的更改還需做另外的探讨。以上為個人總結,歡迎大家拍磚。
=============================================官網的資料
< Previous | Front page | Next >
- Tools
- Attachments (0)
- Page History
- Restrictions
- Send to Kindle
- Info
- Link to this Page…
- View in Hierarchy
- View Wiki Markup
- Export to HTML
- Export to EclipseHelp
- Export to EPUB
- Export to PDF
Class Loading in AS7
Skip to end of metadata
- Added by Stuart Douglas, last edited by Daniel De Leon on Dec 03, 2012 (view change)
Go to start of metadata
Class loading in AS7 is considerably different to previous versions of JBoss AS. Class loading is based on theJBoss Modules project. Instead of the more familiar hierarchical class loading environment, AS7's class loading is based on modules that have to define explicit dependencies on other modules. Deployments in AS7 are also modules, and do not have access to classes that are defined in jars in the application server unless an explicit dependency on those classes is defined.
Deployment Module Names
Module names for top level deployments follow the format deployment.myarchive.war while sub deployments are named likedeployment.myear.ear.mywar.war.
This means that it is possible for a deployment to import classes from another deployment using the other deployments module name, the details of how to add an explicit module dependency are explained below.
Automatic Dependencies
Even though in AS7 modules are isolated by default, as part of the deployment process some dependencies on modules defined by the application server are set up for you automatically. For instance, if you are deploying a Java EE application a dependency on the Java EE API's will be added to your module automatically. Similarly if your module contains a beans.xml file a dependency onWeld will be added automatically, along with any supporting modules that weld needs to operate.
For a complete list of the automatic dependencies that are added see this page.
Automatic dependencies can be excluded through the use of jboss-deployment-structure.xml.
Class Loading Precedence
A common source of errors in Java applications is including API classes in a deployment that are also provided by the container. This can result in multiple versions of the class being created and the deployment failing to deploy properly. To prevent this in AS7, module dependencies are added in a specific order that should prevent this situation from occurring.
In order of highest priority to lowest priority
- System Dependencies - These are dependencies that are added to the module automatically by the container, including the Java EE api's.
- User Dependencies - These are dependencies that are added through jboss-deployment-structure.xml or through the Dependencies: manifest entry for modules or through Class-Path: for jar files.
- Local Resource - Class files packaged up inside the deployment itself, e.g. class files fromWEB-INF/classes or WEB-INF/lib of a war.
- Inter deployment dependencies - These are dependencies on other deployments in an ear deployment. This can include classes in an ear's lib directory, or classes defined in other ejb jars.
WAR Class Loading
The war is considered to be a single module, so classes defined in WEB-INF/lib are treated the same as classes inWEB-INF/classes. All classes packaged in the war will be loaded with the same class loader.
EAR Class Loading
Ear deployments are multi-module deployments. This means that not all classes inside an ear will necessarily have access to all other classes in the ear, unless explicit dependencies have been defined. By default theEAR/lib directory is a single module, and every WAR or EJB jar deployment is also a separate module. Sub deployments (wars and ejb-jars) always have a dependency on the parent module, which gives them access to classes inEAR/lib, however they do not always have an automatic dependency on each other. This behaviour is controlled via theear-subdeployments-isolated setting in the ee subsystem configuration:
|
By default this is set to false, which allows the sub-deployments to see classes belonging to other sub-deployments within the .ear.
For example, consider the following .ear deployment:
|
If the ear-subdeployments-isolated is set to false, then the classes in web.war can access classes belonging to ejb1.jar and ejb2.jar. Similarly, classes from ejb1.jar can access classes from ejb2.jar (and vice-versa).
The ear-subdeployments-isolated element value has no effect on the isolated classloader of the .war file(s). i.e. irrespective of whether this flag is set to true or false, the .war within a .ear will have an isolated classloader and other sub-deployments within that .ear will not be able to access classes from that .war. This is as per spec. |
If the ear-subdeployments-isolated is set to true then no automatic module dependencies between the sub-deployments are set up. User must manually setup the dependency withClass-Path entries, or by setting up explicit module dependencies.
Portability The Java EE specification says that portable applications should not rely on sub deployments having access to other sub deployments unless an explicit Class-Path entry is set in the MANIFEST.MF. So portable applications should always use Class-Path entry to explicitly state their dependencies. Class-Path: /X:/libs/libFile.jar |
It is also possible to override the ear-subdeployments-isolated element value at a per deployment level. See the section on jboss-deployment-structure.xml below. |
Dependencies: Manifest Entries
Deployments (or more correctly modules within a deployment) may set up dependencies on other modules by adding aDependencies: manifest entry. This entry consists of a comma separated list of module names that the deployment requires. The available modules can be seen under themodules directory in the application server distribution. For example to add a dependency on javassist and apache velocity you can add a manifest entry as follows:
Dependencies: org.javassist export,org.apache.velocity export services,org.antlr
Each dependency entry may also specify some of the following parameters by adding them after the module name:
- export This means that the dependencies will be exported, so any module that depends on this module will also get access to the dependency.
- services By default items in META-INF of a dependency are not accessible, this makes items fromMETA-INF/services accessible so services in the modules can be loaded.
- optional If this is specified the deployment will not fail if the module is not available.
- annotations If a jandex index has be created for the module these annotations will be merged into the deployments annotation index. TheJandex index can be generated using the Jandex ant task , and must be named META-INF/jandex.idx. Note that it is not necessary to break open the jar being indexed to add this to the modules class path, a better approach is to create a jar containing just this index, and adding it as an additional resource root in the module.xml file.
Adding a dependency to all modules in an EAR Using the export parameter it is possible to add a dependency to all sub deployments in an ear. If a module is exported from aDependencies: entry in the top level of the ear (or by a jar in the ear/lib directory) it will be available to all sub deployments as well. |
To generate a MANIFEST.MF entry when using maven put the following in your pom.xml: pom.xml
|
Class Path Entries
It is also possible to add module dependencies on other modules inside the deployment using theClass-Path manifest entry. This can be used within an ear to set up dependencies between sub deployments, and also to allow modules access to additional jars deployed in an ear that are not sub deployments and are not in theEAR/lib directory. If a jar in the EAR/lib directory references a jar viaClass-Path: then this additional jar is merged into the parent ear's module, and is accessible to all sub deployments in the ear.
Global Modules
It is also possible to set up global modules, that are accessible to all deployments. This is done by modifying the configuration file (standalone/domain.xml).
For example, to add javassist to all deployments you can use the following XML:
standalone.xml/domain.xml
|
Note that the slot field is optional and defaults to main.
JBoss Deployment Structure File
jboss-deployment-structure.xml is a JBoss specific deployment descriptor that can be used to control class loading in a fine grained manner. It should be placed in the top level deployment, inMETA-INF (or WEB-INF for web deployments). It can do the following:
- Prevent automatic dependencies from being added
- Add additional dependencies
- Define additional modules
- Change an EAR deployments isolated class loading behaviour
- Add additional resource roots to a module
An example of a complete jboss-deployment-structure.xml file for an ear deployment is as follows:
jboss-deployment-structure.xml
|
The xsd for jboss-deployment-structure.xml is available at https://github.com/jbossas/jboss-as/blob/master/build/src/main/resources/docs/schema/jboss-deployment-structure-1_2.xsd |
Accessing JDK classes
Not all JDK classes are exposed to a deployment by default. If your deployment uses JDK classes that are not exposed you can get access to them using jboss-deployment-structure.xml with system dependencies:
Using jboss-deployment-structure.xml to access JDK classes
<
jboss-deployment-structure
xmlns
=
"urn:jboss:deployment-structure:1.1"
>
<
deployment
>
<
dependencies
>
<
system
export
=
"true"
>
<
paths
>
<
path
name
=
"com/sun/corba/se/spi/legacy/connection"
/>
</
paths
>
</
system
>
</
dependencies
>
</
deployment
>
</
jboss-deployment-structure
>