标签:
详细参考: http://tech.it168.com/j/2007-06-27/200706271521984.shtml
1) org.jboss.Main.main(String[]) 为入口 .
2) main 函数创建一个名叫” jboss ”的线程组 , 然后创建一个属于该组的线程 , 在线程中执行 boot 方法 .
3) boot 方法首先处理 main 函数中的参数 ( 及一些其它的系统环境设置 ), 接着就用系统的属性创建了org.jboss.system.server.ServerLoader 实例 [new ServerLoader(props)].
4) ServerLoader 注册 Jboss 相关的类路径 , 包括 XML 解析器 , jboss-jmx.jar, concurrent.jar 及其它的一些额外的类路径 .
5) ServerLoader 通过 load(ClassLoader) 方法创建 Jboss Server 实例 . 参数 ClassLoader 是 ClassLoader parentCL = Thread.currentThread(). getContextClassLoader( ) 得到的当前线程的类加载器 . 创建的Server 实例是 org.jboss.system.server.Server 接口的实现 . load(ClassLoader) 方法的细节:
Ø 用 jar 包及在 ServerLoader 中注册的类路径创建一个 URLClassLoader 的实例 , 把传入的 ClassLoader作为该 URLClassLoader 的 parent.
Ø Server 接口的实现类由系统属性 jboss.server.type 决定 , 默认是 org.jboss.system.server.ServerImpl.
Ø URLClassLoader 通过无参构造函数加载 Server 接口实现的实例 . 在加载前把当前线程的类加载器置为该URLClassLoader, 在加载完成后再置回之前传入的 ClassLoader.
6) Server 实例用系统属性进行初始化 [server.init(props)].
7) 服务起动 [server.start()]. 起动过程的默认实现如下 :
Ø 把当前线程类型加载器置为加载该 Server 接口实现实例的 ClassLoader.
Ø 在 jboss 域内 , 通过 MBeanServerFactory 的 createMBeanServer(String) 方法创建 MbeanServer 实例 .
Ø 在 MBean Server 上注册 ServerImpl 和 ServerConfigImpl 两个 MBean.
Ø 初始化统一的类加载仓库 (unified class loader repository), 用来装载服务器配置目录及其它可选目录下的jar 文件 . 对于每一个 jar 文件和类目录都会创建一个相应的 org.jboss.jmx.loading.UnifiedClassLoader实例 , 并且注册到统一的仓库中 . 其中一个 UnifiedClassLoader 实例会被设置为当前线程上下文的ClassLoader. [?: This effectively makes allUnifiedClassLoaders available through the thread context class loader.]
Ø 接下来创建 org.jboss.system.ServiceController 的 MBean 实例 . ServiceController 管理 JBoss MBean服务的生命周期 .
http://www.cnblogs.com/svennee/p/4075514.html
Classloader 类加载器,用来加载 Java 类到 Java 虚拟机中。与普通程序不同的是。Java程序(class文件)并不是本地的可执行程序。当运行Java程序时,首先运行JVM(Java 虚拟机),然后再把Java class加载到JVM里头运行,负责加载Java class的这部分就叫做Class Loader。
JVM本身包含了一个ClassLoader称为Bootstrap ClassLoader,和JVM一样,BootstrapClassLoader是用 本地代码实现的,它负责加载核心JavaClass(即所有java.*开头的类)。另外JVM还会提供两个ClassLoader,它们都是用Java语言编写的,由BootstrapClassLoader加载;其中Extension ClassLoader负责加载扩展的Javaclass(例如所有javax.*开头的类和存放在JRE的ext目录下的类),ApplicationClassLoader负责加载应用程序自身的类。
当运行一个 程序的时候,JVM启动,运行bootstrapclassloader,该ClassLoader加载java核心API(ExtClassLoader和AppClassLoader也在此时被加载),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。
注: 学ClassLoader看OSGI程序应用
什么时候JVM会使用ClassLoader加载一个类呢?当你使用java去执行一个类,JVM使用ApplicationClassLoader加载这个类;然后如果类A引用了类B,不管是直接引用还是用Class.forName()引用,JVM就会找到加载类A的ClassLoader,并用这个ClassLoader来加载类B。JVM按照运行时的有效执行语句,来决定是否需要装载新类,从而装载尽可能少的类,这一点和编译类是不相同的。
Why use your own ClassLoader?
似乎JVM自身的ClassLoader已经足够了,为什么我们还需要创建自己的ClassLoader呢?
因为JVM自带的ClassLoader只是懂得从本地文件系统加载标准的java class文件,如果编写你自己的ClassLoader,你可以做到:
1)在执行非置信 代码之前,自动验证数字签名
2)动态地创建符合用户特定需要的定制化构建类
3)从特定的场所取得java class,例如数据库中
4) 等等
事实上当使用Applet的时候,就用到了特定的ClassLoader,因为这时需要从网络上加载java class,并且要检查相关的安全信息。
应用服务器大都使用了ClassLoader技术,即使你不需要创建自己的ClassLoader,了解其原理也有助于更好地部署自己的应用。
当你决定创建你自己的ClassLoader时,需要继承java.lang.ClassLoader或者它的子类。在实例化每个ClassLoader对象时,需要指定一个父对象;如果没有指定的话,系统自动指定ClassLoader.getSystemClassLoader()为父对象。
所以当创建自己的Class Loader时,只需要 重载findClass()这个方法。
当一个javaclass被加载到JVM之后,它有没有可能被卸载呢?我们知道Win32有FreeLibrary()函数,Posix有 dlclose()函数可以被调用来卸载指定的 动态连接库,但是Java并没有提供一个UnloadClass()的方法来卸载指定的类。
在Java中,java class的卸载仅仅是一种对系统的优化,有助于减少应用对内存的占用。既然是一种优化方法,那么就完全是JVM自行决定如何实现,对Java开发人员来说是完全透明的。
在什么时候一个java class/interface会被 卸载呢?Sun公司的原话是这么说的:"class or interfacemay be unloaded if and only if its class loader is unreachable. Classesloaded by the bootstrap loader may not be unloaded."
事实上我们关心的不是如何卸载类的,我们关心的是如何更新已经被加载了的类从而更新应用的功能。JSP则是一个非常典型的例子,如果一个JSP文件被更改了, 应用服务器则需要把更改后的JSP重新编译,然后加载新生成的类来响应后继的请求。
其实一个已经加载的类是无法被更新的,如果你试图用同一个ClassLoader再次加载同一个类,就会得到异常(java.lang.LinkageError: duplicate classdefinition),我们只能够重新创建一个新的ClassLoader实例来再次加载新类。至于原来已经加载的类,开发人员不必去管它,因为它可能还有实例正在被使用,只要相关的实例都被内存回收了,那么JVM就会在适当的时候把不会再使用的类卸载。
使用 线程上下文类加载器, 可以在执行线程中, 抛弃双亲委派加载链模式, 使用线程上下文里的类加载器加载类.
典型的例子有, 通过 线程上下文来加载第三方库jndi实现, 而不依赖于双亲委派.
大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。
当然, 好东西都有利弊. 使用 线程上下文加载类, 也要注意, 保证多根需要通信的线程间的类加载器应该是同一个, 防止因为不同的类加载器, 导致类型转换异常(ClassCastException).
参考资料及图片来源——Understanding J2EE Application Server Class Loading Architectures
http://www.baike.com/wiki/classloader
如图所示:
classpath对应的JVM中的类和jboss-home/lib目录下的类处于最底层,我们暂且称之为“低级”层;
deploy目录中应用中的类和server/xxx/lib中的类处于中间层,称之为“中级”层;
WAR包中的类处于最高级,称之为“高级”层;
jboss的类加载机制为高级层中的类可以应用中低级层中的类,中级层中的类可以引用低级层中的类,反之则不行。即处于上层中的类对于处于下层中的类是不可见的。
此种类加载机制可以让我们在发布的多个应用程序共享类包。但是也有其缺点:如果两个application需要同一个类包的不同版本,这种方式无法解决了。可以通过配置范围来解决。
http://blog.csdn.net/daydaylearn/article/details/7949186
1. 概念介绍
UCL : org.jboss.mx.loading.UnifiedClassLoader3 ,它继承标准的java.net.URLClassLoader,覆盖了标准parent delegation模型以使用共享class和资源仓库
仓库(responsitory): org.jboss.mx.loading.UnifiedLoaderRepository3。
平面模型:为了热deploy模块的需要,JBoss实现了自己的类装载器UnifiedClassLoader3,一般来说,一个顶层的deployment就有一个UnifiedClassLoader3实例为之工作。一个deployment所装载的类,其他 deployment是可见的。全局唯一的UnifiedLoaderRepository3实例用于管理这些类,以及装载它们的UnifiedClassLoader3。UnifiedLoaderRepository3实例和UnifiedClassLoader3实例是一对多的关系。
2. jboss classloader机制
首先看一下各种类型的deployer。不同的deployer是根据文件的后缀进行区分。MainDeployer起到一个controller的作用,根据不用的后缀分发到不同的deployer进行处理。如果是*.ear,则会由EARDeployer进行载入。
应用的加载时一个 Top Level Deployer + Top Level Ucl。 举个例子,比如发布一个a.ear应用,ear应用中会包含一个*.war。这时候就会涉及deployer选择问题。jboss采取的原则就是按Top Level,根据最顶层的应用选择deployer,继而也有了top level ucl的概念。由顶级的ucl来加载整个应用。这里需要注意的是war的部署有点特别。它只是将自身添加到ucl的classpath域中,而war下的WEB-INF/lib/*.jar,则是由WebAppClassloader来加载。可调整ear下的 META-INF/jboss-service.xml中的UseJbossWebLoader属性。如果设置为true,故名思义就是用ucl来加载war下的jar包。否则就是采用独立的classloader加载。
再看一下ucl的加载过程,首先会调用仓库去loadclass,仓库在查找无果的情况下会回调各自的UCL去加载本地库。
3. jboss scope配置
意思是说,scope配置只能是顶级下的配置,比如一个.sar中包含.war都配置了scope,只有.sar下的 META-INF/jboos-service.xml才有效。这也与前面 TOP level UCL + TOP Devloper相对应。
针对.sar,你可以在jboss-service.xml中,添加如下配置:
针对.ear,你可以在jboss-app.xml添加如下配置:
针对 .war,你可以在jboss-web.xml添加如下配置:
注意,在最新的4.2.1版本中,<class-loading>标签已经不再使用,你可以直接配置:
针对这两种方式的配置,4.0.5版本都支持。
针对典型的ear+war应用,*.ear/META-INF/jboos-service.xml,用于调整war的加载方式。
配置java2ClassLoadingCompliance为true,则表明是选择parent first。典型的classloader的双亲委托模型,否则是采用child first,先从自身加载,找不到再相父类请求。
配置UseJBossWebLoader为false,则webapp的加载通过独立于jboss的classloader进行加载。
http://agapple.iteye.com/blog/791940
原文:http://blog.csdn.net/youfly/archive/2009/02/12/3884062.aspx
部署器(Deployers) 是一种将组件整合进JBoss服务器的一种机制,部署器同时也是大多数的UCL实例的创建者,MainDeployer是主要的创建者。 MainDeployer通过init方法在部署的初期创建UCL。UCL是通过调用 DeploymentInfo.createClassLoaders()方法来创建的。只有最高层的DeploymentInfo(每一种部署组件都有 对应的DeploymentInfo)才进行实际的UCL创建工作。其他的子部署(subdeployments)将设置他们的classpath到父 DeploymentInfo创建的UCL中。每个部署都有一个独立的URLClassLoader,并且该部署将自身的部署url作为 classpath的一部分添加到这个ClassLoader中,这主要是用作载入本地资源如部署描述符等信息。下图提供了一个图例说明了 Deployers,DeploymentInfos,Classloaders的交互过程。
这个图说明了一个包含EJB及WAR子部署的EAR部署过程。EJB的部署通过引用了lib/util.jar工具包。WAR在它的WEB- INF/classes包含了java类,在它的WEB-INF/lib/目录里包含了jbosstest-web-util.jar包。每一个部署都有 它们自己的DeploymentInfo实例,并且有一个URLClassLoader指它他们的部署包。和some.ear关联的 DeploymentInfo仅有一个UCL被创建。ejbs.jar和web.war DeploymentInfos将添加它们的部署包到some.ear UCL的classpath中。并且共享这个UCL作为它们的部署UCL。EJBDeployer同时也会添加在manifestf里引用的jar到 EAR的UCL中。
WARDeployer的行为和别的部署器有些不同,它仅仅添加了它的WAR包到它的DeploymentInfo UCL的classpath中。WAR包里的WEB-INF/classes和WEB-INF/lib目录将由Server容器的ClassLoader 来载入。servlet容器的class loader将WAR包的DeploymentInfo UCL作为它的父ClassLoader,并进行委派,但是servlet容器的class loader并不是boss class loader repository的一部份。因此,在WAR包里的类对于别的组件将是不可见的。如果需要将类在各个组件(如EJBs,MBeans)里进行共享,则需 要将类载入到共享的class loader repository中,而不管这些类是包含在SAR,EJB部署中,还是通过jar包的manifest文件里的Class-Path条目进行引用的共 享类。在SAR的情况下,在服务部署描述里的classpath元素和jar的manifest Class-Path具有相同的效果和目的。
http://blog.csdn.net/dknypxt/article/details/5671944
下图是JBoss class loading体系结构:
上图是JBoss核心ClassLoader组件,它的核心部分是org.jboss.mx.loading.UnifiedClassLoader3(UCL)。 它继承标准的java.net.URLClassLoader,覆盖了标准parent delegation模型以使用共享class和资源仓库。这个共享的仓库是
org.jboss.mx.loading.UnifiedLoaderRepository3。 每一个UCL关联到单一的一个
UnifiedLoaderRepository3
, 并且一个
UnifiedLoaderRepository3
通 常拥有多个UCL。一个UCL可能具有多个URL用来载入class和资源。部署器使用最顶层的部署单元UCL作为它的共享classloader,并且 所有的部署都关联的这个ClassLoader。
当一个UCL请求载入一个类时,它首先去它关联的仓库cache查找,看是否这个类已被 载入。仅当这个类在仓库里不存在时,它才由UCL载入到仓库中。通常的,所有UCL实例共享一个UnifiedLoaderRepository3。 这意味着UCL是一个扁平的ClassLoader。
下面是UnfiedClassLoader3.loadClass(String, boolean)完整的执行序列:
检查UnifiedClassLoader3关联的
UnifiedLoaderRepository3
类 cache。如果类在cache找到,则返回这个类。
否则,检查UnfiedClassLoader3
是否能够载入这个类。它本质上调用了父类URLClassLoader.loadClass(String, boolean)
方法来查看这个类是否存在于当前ClassLoader关联的URL里,或者在当前ClassLoader的父 ClassLoader里。如果类被找到,则将它放到的仓库的Class cache里,并返回找到的类。
否 则,仓库根据包名到UCl的印射查询其他的UCL是否有能力载入这个类。当一一个UCL添加到仓库中时,将建立UCL载入类的包名到当前这个UCL的印射 关系。这就能够快速的确定哪一个UCL能够载入当前类。 然后UCLs根据每个UCL添加到仓库里时指的顺序请求载入指定的类。如果其中一个UCL能够找到这个类,则返回这个类,如果都不能找到,则抛出java.lang.ClassNotFoundException
异 常。
http://blog.csdn.net/dknypxt/article/details/5671947
下图展示了一个包含EBJ模块和WAR模块时JBoss ClassLoader的一个结构。该结构没有使用偏平的JBoss ClassLoader,并且也没有画出在对EAR的Classloader进行隔离的时候JBoss类仓库的层次结构。
下面对这个图进行说明:
在现有的Jboss类装载结构中,有一些好处也有一些坏处。
好处包括:
坏处包括:
JBoss启动和ClassLoader的关系:
下图简单的描述了JBoss启动过程和ClassLoader结构之间的简单关系:
main大致的执行序列图如下:
在这里需要注意的,这些被main方法调用的方法,它们执行的TCL都是SystemClassLoader,而不管这些方法是 ServerLoader实例上的还是Server实例上的。在被调用的方法返回前,被调用方法保证将TCL还原为调用前的那个TCL。
http://blog.csdn.net/dknypxt/article/details/5671941
由于平时项目中用到的还是JBoss 4.2.x所以我这里的分析时针对这个版本的,不一定适用其他JBoss版本。
下面言归正传。
JBoss为了实现类的共享引入了class loader repository的概念,并且设计了org.jboss.mx.loading.UnifiedClassLoader3 (UCL)来完成sharing classes的主要功能。
UCL和UnifiedLoaderRepository3 一对多的关系,默认情况下一个jboss实例中只有一个UnifiedLoaderRepository3实例,这个UnifiedLoaderRepository实例会和所有的UCL关联。
NoAnnotationClassLoader是UCL的父classloader用来加载$JBOSS_HOME/lib下的jar,system class loader是NoAnnotationClassLoader的父classloader。
这几个对象的关系请见下图
从上图可以看出默认情况下所有的UCL共享一个Repository,通过Repository可以实现class的共享。UnifiedLoaderRepository3实例中维护着两个容器,一个是class cache:这个容器很明显缓存了一些class,这样可以提高loadClass方法的执行效率;另一个是packagesMap:这个map维护的是类的包名和UCL的mapping关系。具体UCL按什么逻辑load class的请看下面的活动图:
UnifiedClassLoader3的继承结构如下图所示,UnifiedClassLoader3的父类RepositoryClassLoader重写了URLClassLoader的loadClass方法,实现了上图的逻辑
下面请看一下相关代码:
RepositoryClassLoader.java
有几点结论可以加深一些印象:
由于jboss对所有UCL的共享机制就会导致出现一些class的版本冲突问题,一些应用加载不到自己的应用需要的class。对于这个问题JBOSS提供了一些解决措施:http://community.jboss.org/wiki/ClassLoadingConfiguration。后面我会再整理一下此前我遇到过的一个class冲突的case和解决办法。
Tomcat6/7 class loader机制
Tomcat class loader层次结构
Tomcat的class load机制较Jboss来说要简单
当web应用需要load class时先调用WebAppClassloader的loadClass方法,loadClass内部逻辑如下:
具体的代码可以看WebAppClassloader.loadClass(..)
参考文档:
http://community.jboss.org/wiki/JBossClassLoadingUseCases
http://community.jboss.org/wiki/ClassLoadingConfiguration
http://community.jboss.org/wiki/EnableClassloaderLogging
http://agapple.iteye.com/blog/791940
http://seanhe.iteye.com/blog/841723
By default JBoss (prior to version 3.2) uses a flat class loading model that avoids the need to redundantly include classes in different layers. WAR files would only have the web contents and servlets, EJBs their interfaces, implementations and types, etc. Canonical packaging works correctly with this model.
However, if you have applications that cannot share classes because of version conflicts, then you need to isolate the classes from other deployments. Without isolation, common errors seen are ClassCastException, IllegalAccessErrors, VerifyErrors and in general, strange behavior that changes as new deployments are added and removed.
There are two levels of scoping, isolation from other deployments, and isolation that overrides the loading of JBoss server classes. With nested modules, only the top level file may specify class loader scoping. If you have a .ear file containing other modules, only scoping specified in the .ear‘s META-INF/jboss-app.xml is used. This also applies for any other deployment which contains sub-deployments. For example, if a .sar contains a .war deployment, only the .sar META-INF/jboss-service.xml scoping has effect.
For .ear files, in your jboss-app.xml, add the following descriptor fragment construct to enable scoped class loading:
<jboss-app> <loader-repository> com.example:archive=unique-archive-name </loader-repository> </jboss-app>
For .war files, in your jboss-web.xml, the following template applies:
<jboss-web> <class-loading> <loader-repository>com.example:archive=unique-archive-name</loader-repository> </class-loading> </jboss-web>
Note for AS 4.2.x and versions till 5.x: As of at least JBoss 4.2.1, the <class-loading> tag appears to no longer be supported as isolation is ignored. Instead, the following configuration appears to accomplish the same goal:
<jboss-web> <loader-repository> com.example:archive=unique-archive-name </loader-repository> </jboss-web>
Interestingly enough, 4.0.5 seems to support both configurations.*
For .sar files, in your jboss-service.xml, the following template applies:
<server> <loader-repository> com.example:archive=unique-archive-name </loader-repository> </server>
The <loader-repository> elements must be correctly placed within the respective
<jboss-app>, <jboss> and <jboss-web> XML elements.
Check the corresponding DTD found in the docs/dtd directory of the distribution for the complete content model.
Note for 5.x and later versions: The above mentioned configuration might still work with the 4.0.x till 5.x version due to their xsd/dtd, but for versions 5.x and above the old configuration still applies for jboss-web.xml:
The com.example:archive=unique-archive-name strings are JMX ObjectName
strings. These have no particular significance other than that they must be unique.
It might be useful to use the same name as used for the .ear, .war, or .sar file.
For example, for a petstore.ear file, use: com.example:loader=petstore.ear as the repository name.
The loader-repository ObjectName will appear in the JMX-Console (http://localhost:8080/jmx-console/).
This MBean is great for debugging any class-loading issues which might arise.
The hierarchical loaders created from the repository wll appear together under the loader-repository domain name,
com.example in the example.
Use the following constructs to enabled scoped class loading with the deployment classes overriding the server classes.
For jboss-app.xml:
<jboss-app> <loader-repository> com.example:archive=unique-archive-name <loader-repository-config> java2ParentDelegation=false </loader-repository-config> </loader-repository> </jboss-app>
For jboss-web.xml:
<jboss-web> <class-loading java2ClassLoadingCompliance="false"> <loader-repository> com.example:archive=unique-archive-name <loader-repository-config>java2ParentDelegation=false</loader-repository-config> </loader-repository> </class-loading> ...
Note: See comment above regarding web class loader isolation.
For jboss-service.xml:
<server> <loader-repository> com.example:archive=unique-archive-name <loader-repository-config>java2ParentDelegation=false</loader-repository-config> </loader-repository> ...
The isolated EAR or WAR repository will load its libraries in this order:
WEB-INF/lib (for WARs)
libraries in server/default/lib
tomcat-libraries in server/default/deploy/jbossweb-tomcat50.sar (jboss-3.2.6).
The libraries in server/default/lib get mixed together with jbossweb-tomcat50.sar in no specific order (for details look into the loader-repository in the JMX-console).
In jboss-3.2.3, the jbossweb-tomcat41.sar is configured to use a unified class loader as the web application class loader. This is controlled by the UseJBossWebLoader attribute in the jbossweb-tomcat41.sar/META-INF/jboss-service.xml descriptor. The use of a unified class loader means that the classes available in the war inside of the WEB-INF/classes and WEB-INF/lib are incorporated into the default shared class loader repository. This may not be what you want as its contrary to the default servlet 2.3 class loading model and can result in sharing of classes/resources between web applications. You can disable this by setting this attribute to false.
From 4.0.2 JBoss has changed to the Servlet spec classloading model, i.e. it uses the Tomcat classloader. See the related JIRA Task
From JBoss-3.2.4 the EAR deployer provides a simplified version of the isolation. You can configure all your ears to be in isolated classloader spaces using call by value for remote interfaces.
The EARDeployer is configured in conf/jboss-service.xml for versions 3.x and in deploy/ear-deployer.xml for versions 4.x+
<!-- EAR deployer, remove if you are not using Web layers --> <mbean code="org.jboss.deployment.EARDeployer" name="jboss.j2ee:service=EARDeployer"> <!-- Isolate all ears in their own classloader space --> <attribute name="Isolated">true</attribute> <!-- Enforce call by value to all remote interfaces --> <attribute name="CallByValue">true</attribute> </mbean>
If you want to make JNDI lookups across EARs that are isolated, you need to force
marshalling of the lookup, e.g. if you have the following ejb-ref in your ejb-jar.xml
that references an EJB in an isolated EAR
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <ejb-jar> <enterprise-beans> <session> <ejb-name>SessionA</ejb-name> <home>org.jboss.test.isolation.interfaces.a.SessionAHome</home> <remote>org.jboss.test.isolation.interfaces.a.SessionA</remote> <ejb-class>org.jboss.test.isolation.ejb.a.SessionAEJB</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> <ejb-ref> <ejb-ref-name>ejb/SessionB</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>org.jboss.test.isolation.interfaces.b.SessionBHome</home> <remote>org.jboss.test.isolation.interfaces.b.SessionB</remote> </ejb-ref> </session> </enterprise-beans> </ejb-jar>
In jboss.xml use the full scheme to define the lookup:
<?xml version="1.0" encoding="UTF-8"?> <jboss> <enterprise-beans> <session> <ejb-name>SessionA</ejb-name> <ejb-ref> <ejb-ref-name>ejb/SessionB</ejb-ref-name> <jndi-name>jnp://${jboss.bind.address:localhost}:1099/SessionB</jndi-name> </ejb-ref> </session> </enterprise-beans> </jboss>
You can also use the full scheme in lookups from non-EJB clients such as standalone applications or JSP pages. In this case you would be encoding deployment knowledge into the code - the applications will always use call-by-value even if your needs change. If you are retro-fitting classloader isolation you may also have a lot of lookup code to change, although you should probably have used a constant or lookup service to hold the actual name.
An alternative is to force all JNDI lookups to be call-by-value, which you can do in
/deploy/naming-service.xml (This used to reference
/conf/jboss-service.xml, which is WRONG for 4.0.3) in the section headed JNDI. Change the jboss:service=Naming bean
definition so that the CallByValue attribute reads:
<mbean code="org.jboss.naming.NamingService" name="jboss:service=Naming" xmbean-dd="resource:xmdesc/NamingService-xmbean.xml"> ... <attribute name="CallByValue">true</attribute> ... </mbean>
This is indiscriminate - JBoss will be unable to optimise any JNDI calls any more, but may be appropriate in some circumstances.
The use of call by value and marshalling is very inefficient. It typically means
method invocations take 10 times the cpu. Why? Compare Call By Value with Call By Reference
caller does ejb.someMethod()
invocation is passed through ejb container
container does bean.someMethod()
result is returned to the caller
caller does ejb.someMethod()
invocation is marshalled - the parameters are turned into ObjectStream (a byte[]
)
container with a different classloader unmarshalls - byte[]
-> java Objects - including classloading
invocation is passed through ejb container
container does bean.someMethod()
result is marshalled - the return value is turned into ObjectStream
result is unmarshalled using the caller‘s classloader - byte[]
-> java Object
result is return to the caller
The marshalling and unmarshalling uses a lot of cpu.
Debugging class loading issues
This article is about the new classloader implementation and additional abstractions that use it from JBoss5.JBoss ClassLoader History are not covered by this document.
The JBoss ClassLoader framework is made up of a number of abstractions at different levels.The purpose of this introduction is give a high level overview of what each part of the framework does. The different abstractions exist to accomplish one of the goals of the JBoss ClassLoader project which is to allow different users to consume only the parts they want.
The JBoss ClassLoader project is the runtime implementation of the classloader framework. If you just want the basic functionality of the classloader then you can use this level directly. Here you can create ClassLoaderPolicys that define each classloader‘s rules and link them together to create a peer delegate classloading system. Since this is the runtime model, it is this level that the optional JMX management exists.
The JBoss ClassLoading project is the deployment time framework that allows classloaders to be constructed from ClassLoadingMetaData. Rather than dealing with constructing policies and manually linking them together, you specify requirements and capabilities for each ClassLoading Module. The system then links these requirements to capabilities as they are satisifed and checks their consistency. You can think of this level as a kind of dependency injection framework for classloaders. As this is the deployment time model, it this level that can expose the "managed object" view to the JBoss profile service and management console.
The VFSClassLoader provides an implementation of the ClassLoaderPolicy using the JBoss Virtual File System project.This can be used directly or in the JBoss ClassLoadingframework.
There is a seperate option that allows you to construct your modules insideJBossMicrocontainer configuration. This can be seen in use in the bootstrap configuration files of JBoss5.
Built on top of these layers are the ClassLoading Deployers which allow for easy construction of classloaders from JavaEE deployments (or any other type of deployment). This includes mapping of legacy configuration to the ClassLoadingMetaData.
Additionally there is a MockClassLoaderPolicy which some may find useful to test or implement classloading scenarios in unit tests.
https://developer.jboss.org/wiki/JBossClassLoaderIntroduction
http://blog.163.com/javaee_chen/blog/static/17919507720116149511489/将一个完整的.war包部署到Jboss容器中,启动后报如下错误:
http://liufei-fir.iteye.com/blog/759772初次部署jboss的web应用,把tomcat/weblogic下的工程移植到jboss上发布
一、修改JBOSS应用服务器连接的数据库和端口:
1、端口修改:
4.*版: JBOSS H OME/server−−>default−−>deploy−−>jbossweb.sar−−>server.xml5.∗版: JBOSSHOME/server−−>default−−>deploy−−>jbossweb.sar−−>server.xml5.∗版:
{JBOSS_HOME}/server-->default-->deployers-->jbossweb.deployer-->server.xml
一般oracle的端口是8080,把8080改成其他端口即可:
<Connector port="8888" address="jboss.bind.address"maxThreads="250"maxHttpHeaderSize="8192"emptySessionPath="true"protocol="HTTP/1.1"enableLookups="false"redirectPort="8443"acceptCount="100"connectionTimeout="20000"disableUploadTimeout="true"/>2、连接的数据库各种数据库的连接模