浏览 3451 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (5)
|
|
---|---|
作者 | 正文 |
发表时间:2010-06-27
最后修改:2010-06-27
最近在学习ejb,在JBoss5.1-jdk6.0版本下进行部署和测试,发现一个怪异的抽筋现象,闲话少说,看代码和运行结果: 1、先定义接口: public interface StatelessEjb { public void compute(int i); public int getResult(); } 2、定义ejb @Stateless @Remote public class StatelessEjbBean implements StatelessEjb { private int state; public void compute(int i) { state += i; System.out.println("compute():state="+state); } public int getResult() { System.out.println("getResult():state="+state); return state; } } 3、定义测试的客户端 public class StatelessEjbClient { /** * @param args */ public static void main(String[] args) throws NamingException { InitialContext ic = new InitialContext(); //第一次会话 StatelessEjb ejb = (StatelessEjb) ic.lookup("StatelessEjbBean/remote"); System.out.println(ejb.getResult()); ejb.compute(1); System.out.println(ejb.getResult()); ejb.compute(1); System.out.println(ejb.getResult()); ejb.compute(1); System.out.println(ejb.getResult()); System.out.println("---------------------------------"); //第二次会话 StatelessEjb ejb2 = (StatelessEjb) ic.lookup("StatelessEjbBean/remote"); System.out.println(ejb2.getResult()); ejb2.compute(1); System.out.println(ejb2.getResult()); ejb2.compute(1); System.out.println(ejb2.getResult()); ejb2.compute(1); System.out.println(ejb2.getResult()); System.out.println(ejb.equals(ejb2)); System.out.println(ejb == ejb2); } } 在正确部署后运行客户端,抽筋现象出现,可能出现多种运行结果,下面给出典型的两种: 可能出现的运行结果1: 测试客户端的运行结果: 0 0 0 0 --------------------------------- 0 0 0 0 true false JBoss服务器端的输出结果: 18:14:48,390 INFO [STDOUT] getResult():state=0 18:14:48,406 INFO [STDOUT] compute():state=1 18:14:48,421 INFO [STDOUT] getResult():state=0 18:14:48,421 INFO [STDOUT] compute():state=2 18:14:48,437 INFO [STDOUT] getResult():state=0 18:14:48,453 INFO [STDOUT] compute():state=3 18:14:48,453 INFO [STDOUT] getResult():state=0 18:14:48,718 INFO [STDOUT] getResult():state=0 18:14:48,718 INFO [STDOUT] compute():state=4 18:14:48,734 INFO [STDOUT] getResult():state=0 18:14:48,750 INFO [STDOUT] compute():state=5 18:14:48,765 INFO [STDOUT] getResult():state=0 18:14:48,781 INFO [STDOUT] compute():state=6 18:14:48,796 INFO [STDOUT] getResult():state=0 可能出现的运行结果2: 测试客户端的运行结果: 0 1 2 3 --------------------------------- 3 4 5 6 true false
JBoss服务器端的输出结果: 18:26:56,875 INFO [STDOUT] getResult():state=0 18:26:56,906 INFO [STDOUT] compute():state=1 18:26:56,921 INFO [STDOUT] getResult():state=1 18:26:56,937 INFO [STDOUT] compute():state=2 18:26:56,953 INFO [STDOUT] getResult():state=2 18:26:56,968 INFO [STDOUT] compute():state=3 18:26:56,984 INFO [STDOUT] getResult():state=3 18:26:57,000 INFO [STDOUT] getResult():state=3 18:26:57,015 INFO [STDOUT] compute():state=4 18:26:57,031 INFO [STDOUT] getResult():state=4 18:26:57,046 INFO [STDOUT] compute():state=5 18:26:57,046 INFO [STDOUT] getResult():state=5 18:26:57,062 INFO [STDOUT] compute():state=6 18:26:57,078 INFO [STDOUT] getResult():state=6
由于目前为止没有弄清楚原因,本人简单分析原因可能如下(可能分析有误,请多指教): 1、可能是JBoss的bug。这个是最能解释上面原因的,也可能是最不靠谱的。 2、针对第一种运行结果,是不是gerResult()在返回时直接取缓存,从而使结果是0.
欢迎大家给出正确的原因分析,谢谢!!
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-06-27
楼主理解错了无状态的EJB。无状态的EJB不应该保存对象的状态信息,比如这里的state,Stateless bean的状态是不确定的,不是JBoss的Bug。
|
|
返回顶楼 | |
发表时间:2010-06-28
最后修改:2010-06-28
mercyblitz 写道 楼主理解错了无状态的EJB。无状态的EJB不应该保存对象的状态信息,比如这里的state,Stateless bean的状态是不确定的,不是JBoss的Bug。
状态不确定可以理解,但jboss端的这段结果太异常了,理解不了(同一个变量竟然有不同的值): 18:14:48,390 INFO [STDOUT] getResult():state=0 18:14:48,406 INFO [STDOUT] compute():state=1 18:14:48,421 INFO [STDOUT] getResult():state=0 18:14:48,421 INFO [STDOUT] compute():state=2 18:14:48,437 INFO [STDOUT] getResult():state=0 18:14:48,453 INFO [STDOUT] compute():state=3 18:14:48,453 INFO [STDOUT] getResult():state=0 18:14:48,718 INFO [STDOUT] getResult():state=0 18:14:48,718 INFO [STDOUT] compute():state=4 18:14:48,734 INFO [STDOUT] getResult():state=0 18:14:48,750 INFO [STDOUT] compute():state=5 18:14:48,765 INFO [STDOUT] getResult():state=0 18:14:48,781 INFO [STDOUT] compute():state=6 18:14:48,796 INFO [STDOUT] getResult():state=0 同一个类中的变量state,在两个方法中得到的值居然不一样?! |
|
返回顶楼 | |
发表时间:2010-06-28
一个无状态的SessionBean,你是不能假设两次调用的是服务器端的同一个对象的。这里有两个问题:
1. 你的ejb是客户端,跟服务器端的实现是无关的。 2. stateless session bean里面用类变量是标准的anti-pattern。你得到的结果只能说,这一次服务器端用了两个或以上的实例来响应你的调用,一个响应compute(),另外一个或多个响应getResult()。 |
|
返回顶楼 | |
发表时间:2011-04-04
我对两次引用不相等表示不能理解,为什么呢?按照无状态会话Bean的特性,应该是在初始化的时候,容器已经创建无状态会话Bean对象,并且初始化成员属性,所有打印出state为0,很正常,但是容器一般情况下是不会再次创建另一个无状态会话Bean的,无状态会话Bean是存放在一个对象池里面的,当下一次再次需要的时候,容器会再次把已经创建的Bean对象交给客户端,但是当第二次引用的时候,为什么这两个引用不相等呢?
至于state一直在累加,我猜想会不会是创建了两个Bean实例呢? 我很菜,班门弄斧,希望大牛们指点一下,很不解啊? |
|
返回顶楼 | |
发表时间:2011-04-05
你又没指定单例,当然会产生多个无状态Bean。产生多少个实例受不同服务器实现和你的配置而不同。这种Bean有可能只产生1个,也可能产生很多,从对象池拿出的时候,你是无法确定到底是哪个的,只能说是一个空闲的Bean。
对这个Bean的内部属性,除了在初始化时候一样外,是不做任何保证的。因为这是无状态的。你如果要它返回的是你刚才累加的,那么应该使用有状态Bean。 |
|
返回顶楼 | |
发表时间:2011-04-05
谢谢,猫咪,初学者多向你学习一下!
|
|
返回顶楼 | |
发表时间:2011-04-08
最后修改:2011-04-08
在服务器日志上把调用的类句柄打印出来看看就知道了。
另外有个问题,楼主在Stateless Bean里放个变量要作什么用呢? |
|
返回顶楼 | |