花费了两天时间,发现tomcat 4.1.27与tomcat4.1.24区别

这个区别是从JBoss 3.22RC和JBoss 3.22上发现的。
同样的包含Struts的ear发布包,在JBoss 3.22RC上运行正常,而在JBoss 3.22下运行出错,在排除了classloader等容器原因之外,发现是Web容器问题,将ear分解成war在这两个版本中测试,果然。

JBoss 3.22RC使用的是tomcat 4.1.24版本,而Jboss 3.2.2使用的是tomcat 4.1.27版本,后者在re-deploy Web包时,调用同样的程序,会报校验错误,同样的程序拷贝到Tomcat 4.1.24下运行正常。

开源代码好是好,陷阱可真不少 !

?? 一团雾水. 要说什么?

JBoss 3.22RC和JBoss 3.22在classloader机制上有区别,这给部署程序带来不方便。

例如:我的应用程序有很多可重用组件,那么多个应用程序需要这些重用组件时,在容器class loader时就有问题,应用程序是基于组件的、共存但是独立的、可重新加载的。

再可重新加载这方面,就是同一容器的不同版本也不一样。

应用程序之间的相关性:
一般来说,应用程序之间的相关性应该减至最小,J2EE 1.3中没有满足这一点的可用机制。需要相关性的时候,可以从两个方面考虑,这取决于你希望共享代码对所有应用程序是可见的,还是只对某些应用程序可见:

第一:对所有应用程序。为了使共享代码对所有应用程序是可见的,需要把这些共享代码放入JRE扩展目录(当启用服务器时,通过-classpath包括它们),或者使用供应商特定的机制。在这一级别上修改代码可能需要重启服务器。
第二:对某些应用程序。 要使共享代码只对某些应用程序是可见的,需要在每个应用程序里复制这些共享代码,或者使用供应商特定的配置选项。这儿需要考虑的一个重要事项是:一个共享类的一个对象是否必须对这些应用程序是可见的。如果是,则复制这些共享程序是无效的,因为该类被复制,而如前所述,虚拟机认为它们是不同的类。

选择“对某些应用程序是可见的”是很不理想的。因为复制增加了风险和内存占用,还会导致版本问题;而依赖于供应商特定的机制则降低了可移植性。在容器级别上部署是一个选择,但可能导致这些共享代码可见度过高,还可能会限制应用程序重新加载。

我的应用程序是选择了“对某些应用程序是可见的”,所以在JBoss 3.22和jBoss 3.2.2RC2部署时出现不同的结果。

我想说的是:J2EE中,类加载机制是非常复杂而且耗时的,不同容器的实现机制不一样,必须研究透彻,摘引下面一句话:
"如果你曾经花费数小时的时间调试诸如ClassNotFoundException、 NoClassDefFoundError 或者 ClassCastException的这样一些异常,那么肯定你不是唯一这样做的人。"

JBoss 3.2 和JBoss 3.0有一个重要不同处是,JBoss 3.2缺省classloader是唯一的unified 。

因此过去在JBoss 3.0下部署的两个ear包,如果其中有公用的组件,JBoss 3.0不会报错,但是JBoss 3.2就会报出:
Duplicate class found出错

JBoss's class loading architecture needs a little getting used to.

JBoss uses the concept of class loader repository. For any dynamically deployed file, such as EAR, WAR, EJB jar, RAR, and SAR files each is loaded with a new subordinate class loader. However they also register themselves with a loader repository.

These class loaders will first ask the repository and then load classes from themselves.

They may also decide to become the head of a new loader repository. Classes loaded into child loader repositories are not visible to parent loader repositories.

The order in which the class loaders are added to the repository do matter.

The Russian doll model.

Add this jboss-app.xml along side with application.xml:

<jboss-app>
<loader-repository>
hello:service=LoaderRepository
</loader-repository>
</jboss-app>


谢谢,谢谢,受益匪浅; 对JBOSS也是刚用,试过3.2.2. 一定下去后深刻体会.

我也是这么认为,我是初学者,所以用WLS,待入门后,再专一下jboss,毕竟调试这些东西,是初学者很头疼的问题.

另: 好象论坛的字都变大了.

不知道Banq是怎么解决这个问题的?可否共享一下!

因为性能和稳定性的缘故,我将程序从3.2.1移植到3.2.2。但同时也出现了Banq所说的问题。对于一个多个模块(ear)都需要使用的类在重新部署时会出Duplicate Class的异常。显然这是个很麻烦的事。

不知道Banq如何解决的。

我前面写了,jboss 3.22是使用全局的classloader,所以就不允许你在多个ear出现的相同组件,解决这个问题两个方向:将你的组件单独打包成.jar部署,注意Class-path

还有一个是配置 jboss-app.xml ,设置成每个ear包为唯一的classloader。jboss-app.xml是在ear包中,格式如下:


<?xml version="1.0" encoding="UTF-8"?>
<jboss-app>
<loader-repository>
com.jdon:loader=eStore.ear
</loader-repository>
</jboss-app>

请问在EJB里如何实现这个?格式该如何写?

打包在ear中即可。

请问 JBoss_app.xml位于什么位置,我找不到这个文件,也不知道放在啥地方。很急,请回复,多谢!

是ear包中的。和application.xml放在一起。