Send As SMS

2006-04-02

Java字节码反向工程的另外的用途

http://soja.sourceforge.net/blog/2006/04/java.html 《针对Java开发规则引擎的一种优化》 一文中,我谈到了需要基于字节码分析技术来进行规则引擎的优化工作,实际上,字节码分析技术可能适用的范围会更为广泛,完全可以成为一种通用的底层技术, 从而在多个框架领域发挥重要的作用,这里列举一些应用的场景:

1、Profile。基于字节码分析技术,可以比较简单的在现有字节码中插入Profile用的代码,产生用于Profile的数据收集。
2、Code Coverage Tool。
3、Continuation Framework。基于字节码分析,我们可以重构一个方法,把这个方法变成一个等效的类,使用类变量来替代局部变量,从而实现Continuation的开发。下面是一个示例:

public void mailProcess(){
    Mail mail = waitingEmail();
    String txt = mail.getText();
    if(txt == "Hello"){
         Mail mail2 = waitingEmail();
    }
}

==〉
Class mailProcess {
   Mail mail, mail2;
   String txt;
   int status;

   public void execute(){
        switch(status){
           case 1: goto l1;
           case 2: goto l2;
        }
        mail = waitingEmail(); 
        l1:String txt = mail.getText();
        if(txt == "Hello"){
            mail2 = waitingEmail();
            l2:
        }
    }
}

在这里,waitingEmail这个方法会启动一个任务来接受邮件,同时方法抛出异常,自动的结束当前执行。当异步的任务处理接收到邮件时,将邮件的内 容保存到对象中,系统重新的从l1开时继续执行,通过这样一种字节码处理技术,即可简单的实现Continuation的功能。

4、针对log的优化,很多的java代码并没有使用 if(log.isDebugEnabled) log.debug(...) 模式来处理代码,通过字节码分析技术,我们可以对所有的 log.debug 调用自动的添加上上述的检查代码,从而使得代码可以具有更高的执行效率。这种模式可以认为是在字节码层面上的AOP

总之,字节码分析技术可以让字节码本身成为一个可以操作的对象,而且是在更高的语义层面,从而使得开发人员进一步的从这些内容中解脱出来,提高软件的开发效率。

针对Java开发规则引擎的一种优化

最近,有一种想法是在公司内部的项目中使用规则引擎,drools是一个不错的框架,内置的rete引擎,使得规则处理能够高效的进行。在业务系统如何使 用Rule Engine,这个是一个很有挑战性的考量,我会在后续的blog中进一步的思考这个问题。本文则主要思考如何对Java开发规则,提出一些想法。

drools一般的,使用某种规则语言来进行规则的开发工作,在drools2.1中,就有好多种选择:
  1. Domain Specific Languages
  2. Java Semantic Module
  3. Java Annotation Semantic Module
  4. Groovy Semantic Module
  5. Python Semantic Module
  6. CSharp Semantic Module
虽然是每种开发语言都有特定的客户群和适应层面,我个人则对3比较感兴趣,最主要的这种开发方式可以和Java最为紧密的结合,而且对于使用Java作为语言的开发人员而言,学习的曲线最低。

这里是从 http://drools.codehaus.org/Java+Annotation+Semantic+Module 摘取的一个例子:
import org.drools.semantics.annotation.*;

@DroolsRule
public class Hello {

@DroolsCondition
public boolean isTrader(@DroolsParameter("user") User user) {
return user.getType () == UserType.TRADER;
}

@DroolsCondition
public boolean isMarketOpen(@DroolsParameter("order") Order order,
@DroolsApplicationData("calendar") MarketCalendar calendar{
return calendar.isExchangeOpen(order.getExchange(), order.getTradeTime());
}

@DroolsConsequence
public void consequence(...) {
    	...
}
}
这种开发方式最大的一个好处,就是说这些规则的编写可以利用Java的IDE来进行正确性保证,本文提到的优化则是考虑利用字节码分析的手段,对Condition的方法进行智能化的分析,从而自动的分解成为多个&&(and)模式的Condition。
例如:
public boolean checkCondtion(Order order){
return (order.status == 1) && (order.user != null);
}
可以分解成为
public boolean checkCondition1(Order order){
return order.status == 1;
}
public boolean checkCondition2(Order order){
return order.user != null;
}
除了进行这样的分解之外,优化的引擎还可以利用字节码技术来检查两个条件是否是等效的,从而实现Chain的功能,目前的Drools中暂时还不支持这一技术,因此,实际上会大大的限制使用 Java POJO来开发规则。

此外,还有更多的优化是可以进行的,而且,应该可以较大幅度的提高规则引擎的效率,就是对Condition彼此之间进行推理,比如说,会存在这样的集中关系:
  • C1 ==> C2 当C1满足时,C2肯定满足,此时,不再需要重复的执行对C2的求值
  • C1 ==> !C2,当C1满足时,C2肯定不满足,此时,不需要再次对C2求值
  • !C1 ==> C2,当C1不满足时,C2满足
  • !C1 ==> !C2, 当C1不满足时,C2不满足
  • 更为常见的情况,C1,C2,...Cn满足Hash命中,即计算一个表达式Expr,当其值为V1,V2,...Vn时,C1,C2,...Cn满足,在这种情况下,不需要多次的评估Expr,而只需评估一次即可。
当需要进行上述的更加优化时,有必要打破目前drools的rete引擎,在一个更低的层面上进行优化,为此,可以引入ExprCondition类型, 例如:AndExprCondition, OrExprCondition, NotExprCondition, EqualsExprCondition, etc, 在ExprCondition的层面上可以进行更多的优化。

为此:需要的扩展是:
1、编写字节码分析工具,将Java字节码转换为等效的ExprCondition,这个可以开源的jode基础之上进行。
2、扩展drools,在rete引擎的基础上,支持对ExprCondition的优化。

我个人觉得,如果这个任务能够完成,Drools将可以更为简单、更为高效的在业务软件中进行应用,我会在后续的时间内对这一问题进一步的研究。