解惑

解己之惑,解人之惑

分类:Java (第15页共20页)

Java技术

无状态Session Bean的remove是干嘛的?

我从来没有考虑过这个问题,不过昨天遇到的问题其中有一个就是这个。
代码中调用了无状态Session Bean的remove方法,按照在TSS上的一个讨论的内容看,这个remove方法就是告诉服务器可以把那个Bean重新放到Bean的池子里面,但是其实没有必要,因为一般你的调用结束后服务器自然知道并把那个Bean放回池子。

原文如下:
The app server doesnt have to know anything from the client from the remove() operation, because after each and every method call, the bean is decoupled from the client. We had this discussion with SUN during the branding process and they confirmed that the remove() operation is a no-op on a stateless bean. Can you even fathom for me what remove() might do? According to the lifecycle, the bean goes in the pool immediately after it finishes running, so by the time you call remove() as per the spec, the bean must already be in the pool.

Trust me it does nothing. Read the generated stub source for your app server. Youll see.

艰难的过程

最近在做公司的单元测试框架,本来感觉已经初具规模,可以开始正常的使用了,因为我写了40多个各种类型的测试用例都可以正常工作,另外一个组的同事开始写了一个,他说还是挑的一个最简单的,结果报了一堆的异常,呵呵,其实他是测试Message Driven Bean,代码里面要调用很多其它的东西,出了几个问题,一个是他要使用的一个Entity Bean的finder是我写的表达式不支持的,我只能把那个finder实现掉,然后就是代码中使用了一个Topic,而且不是我们的Server端代码使用的,没有对应的Message Driven Bean处理(框架只能自动发布有对应的Message Driven Bean的Queue或者Topic),这个问题忽略不计了,因为那个Message本来就不需要处理,然后就是另外一个finder方法,我的表达式是支持的,但是死活找不到,结果发现是那个Entity Bean的xdoclet的配置比较特殊,一般的Home接口都是Remote接口的名字加Home,结果那个Bean是加BeanHome,而Aspect的匹配表达式是默认的格式,没有办法,修改我的表达式了,谁让那个Home接口的名字是可配置的呢。
另外两个问题还没有搞定,一个是Stateless Session Bean的remove方法,不知道要做什么,我现在处理了Entity Bean的remove,调用那个的时候会从数据库中删除对应的记录,但是Stateless Session Bean的remove应该做什么呢?
一个是获得Topic,我们的那个Locator接口里面定义了获得各种Bean以及Queue的接口方法,但是没有定义获得Topic的方法,所以代码中都是使用:
Context jndiContext = new InitialContext();
topic = (Topic) jndiContext.lookup(serverDataSendTopicName);
这个lookup的过程框架拦截不到。

MockEJB测试框架之自动发布EJB后续

本来今天已经完成了框架的大部分功能,写的一些测试用例都可以成功执行,但是自动发布是放在BaseTestCase里面的,感觉不好,就重构了一下,扩展了InitialContext类,覆盖了lookup方法(参数为字符串的那个,我们的代码中都是使用的这个),这样代码看起来更好一些的。另外我们的系统里面使用到了一些类似的机制,我为了产品可以进行单元测试还对一些Factory类进行了简单的修改,让他们返回我为了单元测试而写的实现类。如果使用这个扩展的InitialContext类,应该不需要做那些修改了,试了下,发现不行,因为产品的代码好像和Jboss的某些特性进行绑定了,先做简单的重构,以后再研究产品到底使用了JBoss的哪些特性,能否搞定。
代码如下:
阅读全文

matches和find的用法

Matcher类有几个进行匹配的方法,一个是matches,一个是find,前者是将整个输入和表达式进行匹配,而后者只是查找匹配的部分,只要找到匹配的就返回。一个典型的应用就是分析SQL,我们写一个表达式先判断整个SQL是否匹配表达式,如果匹配的话就要进行分析,取出我们想要的部分,但是WHERE条件部分有很多条件,使用group只能取到最后一次匹配的部分(参考以前写的Java正则表达式的性能问题你写的正则表达式有多复杂? ),这个时候就要针对条件再写一个表达式,使用find查找所有的条件了,代码片断如下:
阅读全文

你写的正则表达式有多复杂?

正则表达式的功能是非常强大的,但是要使用好也是不容易的,为了能够解析Entity Bean的Finder中的SQL,我写了可以解析部分SQL的表达式:
一个是可以支持FROM子句中的IN语法的:
SELECT\s+(DISTINCT)?\s*OBJECT\s*\(\s*(\w+)\s*\)\s+FROM\s+(\w+)(?:\s+AS)?\s+\2\s*,\s*IN\s*\(\s*\2\.(\w+)\s*\)\s*(?:\s+AS)?\s*(\w+)\s+
(?:WHERE\s+((?:(AND|OR)?\s*(\2|\5)((?:\.\w+)+)\s*(=|is|<>|>=|>|<|<=)\s*(NOT)?\s*(\??\d+|null|true|false|empty)\s*)*))?
(?:\s*ORDER\s+BY\s+(\2|\5)((?:\.\w+)+)(?:\s*(asc|desc)?))?\s*
阅读全文

Java正则表达式的性能问题

在编写EJB-QL的解析器的时候偶然发现的。
假设要解析的EJB-QL的值为:
SELECT OBJECT(al) FROM AppLibraryConfig al WHERE al.id=?1 AND al.status=true

下面看看不同的表达式Pattern所需要的执行时间,解析的伪代码为:
long start=System.currentTimeMillis();
Pattern pattern = Pattern.compile(getPatternText(), Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(query);
if (matcher.matches()) {
        int groupCount = matcher.groupCount();
        for (int i = 0; i <= groupCount; i++)
        {
            System.out.println("Group " + i + " :[" + matcher.group(i) + "]");
        }
}
System.out.println(System.currentTimeMillis()-start);

现在看看不同的getPatternText()的值得到的不同结果。
阅读全文

Session ID

下午一个朋友问我HttpServletRequest.getSession().getId()和HttpServletRequest.getRequestedSessionId()的差异,其实我以前也没有研究过这个差异,看了下API的说明,前者应该是属于服务器端的概念,这个值是存在于服务器的,后者是客户端的概念,也就是那个值是浏览器提交的。我们知道HTTP连接是无状态的,那么如何维护一个Session呢?其实就是通过这个HttpServletRequest.getRequestedSessionId(),如果大家细心一些,有时候会发现有时候浏览器的地址栏或者状态栏里面的地址后面会带一个sessionId的参数值,这个应该就是那个HttpServletRequest.getRequestedSessionId()的返回值了。而且这个值一般也会存在cookie里面,这样就避免了在每次请求的时候都带在请求的URL里面或者FORM里面,它是随着浏览器和服务器端的Cookie进行交流,对于用户和开发人员是透明的。

Java的日期的缺省格式

在做那个单元测试框架的时候要进行类型转换,对于日期型的值,先转换为String然后可能会转换回Date类型,但是转换回Date类型的时候一直出错,后来没有办法看JDK的源代码,才知道日期的缺省格式比较变态,你要把那种格式的字符串转换回Date需要使用:

new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);

很纳闷为什么不把new SimpleDateFormat()的时候就设置为这种格式,非要在Date类的toString方法中使用这样的格式。

Java参数传递方式

其实这个问题我原来翻译(破除java神话之二:参数是传址的 )、转帖别人的详细解释(Java 应用程序中的按值传递语义 )和专门解释( 我对《Java 应用程序中的按值传递语义》的理解 )过,不过现在看来,原来翻译或者解释的角度是有问题的,从底层的角度解释并不直观,在交流的时候也容易引起误解,最终不能达成一致意见。下面以最终的效果来解释参数的传递方式:

1、对于原始数据类型,也就是int、 long、char之类的类型,是传值的,如果你在方法中修改了值,方法调用结束后,那个变量的值没用改变。
2、对于对象类型,也就是Object的子类,如果你在方法中修改了它的成员的值,那个修改是生效的,方法调用结束后,它的成员是新的值,但是如果你把它指向一个其它的对象,方法调用结束后,原来对它的引用并没用指向新的对象。
阅读全文

Java类的完整构造执行顺序

这里只说一个完整的结果,至于为什么是这样的顺序,可以参考我以前的文章:深入剖析java类的构造方式

  1. 如果父类有静态成员赋值或者静态初始化块,执行静态成员赋值和静态初始化块
  2. 如果类有静态成员赋值或者静态初始化块,执行静态成员赋值和静态初始化块
  3. 将类的成员赋予初值(原始类型的成员的值为规定值,例如int型为0,float型为0.0f,boolean型为false;对象类型的初始值为null)
  4. 如果构造方法中存在this()调用(可以是其它带参数的this()调用)则执行之,执行完毕后进入第7步继续执行,如果没有this调用则进行下一步。(这个有可能存在递归调用其它的构造方法)
  5. 执行显式的super()调用(可以是其它带参数的super()调用)或者隐式的super()调用(缺省构造方法),此步骤又进入一个父类的构造过程并一直上推至Object对象的构造。
  6. 执行类申明中的成员赋值和初始化块。
  7. 执行构造方法中的其它语句。

阅读全文

更早的文章 更新的文章

© 2025 解惑

本主题由Anders Noren提供向上 ↑