Jeffrey's Sky

Go with wind
随笔 - 14, 文章 - 1, 评论 - 15, 引用 - 0
数据加载中……

有关在eclipse上远程debug的问题。

   Java 提供了远程debug的功能,这确实是一件很好的事。它能够帮助我们在一些没有虚机的OS(比如HP,AIX,等等)下调试我们的程序。

   1.建立Remote debug的准备工作。
    a.可以将这些在java命令行中的设置放到一个script中去。例子如下所示:
 
    java -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y  -classpath
    其中,“-Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y”是必须的。suspend=y---表明是在程序启动后hang在那个端口处并监听(如果设为n,则不会hang);address=8787---表明是在远端机器上的端口号。除此之外,在java后也可以添加java的系统环境变量,如-D等等。   
    b.在eclipse中可以通过设立一个remote debug的方式来建立这种连接。  
   2.远程调试时,局部变量的值无法Watch/Inspect问题的解决
    这实际上是由eclipse在build的时候,没有将javac后的option -g加上去。只有当加上 -g这个参数时,所有的调试信息才会被build到class文件中去。
    但ecipse没有提供这样在build时设置参数的user interface。所以,最好的方式就是写一个Ant脚本。
    例子如下,

     <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <project basedir="." default="build" name="ssdv">
    <property name="build.location" value="../ssdv_build"/>
    <property name="debuglevel" value="source,lines,vars"/><!--必须的-->
    <property name="target" value="1.5"/>
    <property name="source" value="1.5"/>
    
    <target name="init">
        <mkdir dir="bin"/>
    </target>
    
    
    <target name="clean">
        <delete dir="bin"/>
    </target>
   
    <target depends="init" name="build-project">
        <echo message="${ant.project.name}: ${ant.file}"/>

        <javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">  <!--必须的-->
            <src path="."/>
            <classpath refid="ssdv.classpath"/>
        </javac>

    </target>
    
</project>
   
     这样,将生成的build工程拷贝到要测试的远程OS。启动脚本,然后就可以看到local variables了。

posted @ 2008-12-12 17:34 Jeffrey Feng 阅读(798) | 评论 (0)编辑 收藏

Drools 规则引擎的使用总结

    前一段时间在开发了一个做文本分析的项目。在项目技术选型的过程中,尝试使用了Drools规则引擎。让它来作为项目中有关模式分析和关键词匹配的任务。但后来,因为某种原因,还是撇开了Drools。现将这个过程中使用Drools的一些经验和心得记录下来。
(一)什么时候应该使用规则引擎
    这实际是一个技术选型的问题。但这个问题又似乎是一个很关键的问题(一旦返工的话,你就知道这个问题是多么重要了)。不知大家有没有过这样的经验和体会。往往在项目开始的时候,总会遇到应该选用什么技术?是不是应该使用最新的技术?或者应该选用什么技术呢(PS:现在计算机软件中的各种技术层出不穷,具有类似功能的技术很多)?
    不管怎么样,这些问题总会困扰着我。比如,这次的这个项目。项目要求是要在一些log文件中(这些log文件都是很大的应用系统所产生的,但由于legacy的原因,log本身的维护和规范工作一直没有得到改善,所以想借助于一些外部应用对这些log做以分析和清洗)抽取出有用的信息。
    于是,第一个想到的就是,这是一个文本挖掘类的项目。但又想,要抽取有用信息,必须得建立一些规则或pattern(模式)。所以,我第一个想到了规则引擎。因为这里面要建立好多规则,而这些规则可以独立于代码级别(放到一个单独的drl文件里)并可以用规则引擎去解析和执行。另一个重要的原因是,我原来用过,比较熟悉。这样,也可以节省开发时间吧。于是,好不犹豫的就开始做了Demo....
    但事实上,在经历了一个多星期的编码、测试后,我发现运用规则引擎实在是太笨拙了。
    (1)首先必须建立一些数据模型。通过这些模型来refer规则文件中的LHS和Action。
    (2)还要考虑规则的conflict。如果有一些规则同时被触发,就要考虑设定规则的优先级或者是设定activiation-group来保证在一个group中的规则只有一个规则可以被触发。
    (3)对于‘流’规则group ruleflow-group的使用。如果要控制在workingmemory中的规则被触发的顺序,则可以将这些规则分组。然后,通过规则建模的方式来实现。但这也添加了一定的effort。修改或者更新不大方便。
    所以,基于上述体会,我更认为规则引擎更适用于那些对非流程性规则匹配的应用。当然,Drools也支持对流程性规则的建模过程。但,这也许不是最好的方式。
(二)Drools规则引擎的使用杂记
    (1)Fact 的变更监听。在Drools里,如果一个Fact通过规则而改变,则需将这种改变通知给规则引擎。这里,一般有两种方式:显式和隐式。
         显式---在drl文件中通过 update、modify来通知;在程序中,通过Fact的引用调用modifyObject等方法来实现。
         隐式---通过在java bean实现property Listener Interface来让引擎自动监听到属性值的变化。我更习惯于这种方式。因为,一般看来凡是在规则引擎中添加到fact都是希望引擎来帮你进行管理的。所以,那它自己看到fact的变化是种很省事的办法。也很简单,就是用java bean property 监听的方式。
         通过StatefulSession来注册。
         调用StatefulSession的某个instance 的insert(Object,true)实现。而这个object是一个java bean。其中,要实现
      
        
private final PropertyChangeSupport changes  = new PropertyChangeSupport( this );
    public void addPropertyChangeListener(final PropertyChangeListener l) {
        this.changes.addPropertyChangeListener( l );
    }

    public void removePropertyChangeListener(final PropertyChangeListener l) {
        this.changes.removePropertyChangeListener( l );
    }
  
        然后在set方法中调用
    this.changes.firePropertyChange( "temp",null,this.temp );
     (2)规则触发的优先级、组设置
    往往,在设计我们自己的规则时,要考虑规则的触发条件。这不仅限于LHS的条件部分,还有规则本身被触发的有些设置等等。这里,列出一些比较常用和有效的规则优先级设置方式,以及需要注意的地方。
         A.通过Salience方式。此值可正可负。越大优先级越高,也会被引擎首先执行。
         B.通过ruleflow-group 方式。实际上,使用这种方式也就是在使用建立规则流的方式。在Eclipse 3.3 中,Drools提供了建立规则流的插件。要在drl的同级目录中建立rf和rfm两个文件(当然,插件会帮助你建立这些)。
        
选择RuleFlow File。
      这里,需要注意的一点是要在启动规则引擎的时候,加入启动rule flow的代码。

     InputStreamReader source = new InputStreamReader(RuleManager.class
                    .getResourceAsStream(rule_path));
           PackageBuilder builder = new PackageBuilder();
            builder.addPackageFromDrl(source);
            builder.addRuleFlow(new InputStreamReader(RuleManager.class
                    .getResourceAsStream(rule_flow_path)));
           Package pkg = builder.getPackage();
            RuleBase ruleBase = RuleBaseFactory.newRuleBase();
            ruleBase.addPackage(pkg);
      然后,在每次启动规则引擎的时候,调用如下方法:

            StatefulSession ss;
            ss.startProcess(flowProgress);
            ss.fireAllRules();

            flowProgress 是一个string类型。这个flow的名字。

这个rule flow图中,显示了一个简单的规则流。如RSA就是一个rule-flow的名字。在这个rule set中可以设定一组rules。这样,就可以分开规则执行的顺序。在于rf和rfm同名的另一个 drl文件中定义这些组的名字。通过关键字 ruleflow-group 来表明。
    C.通过activation-group的方式。通过这种方式,可以exclude一组rule中一旦有一个rule被invoke,而其它rule不会被execute。同时,可以搭配使用salience关键字来标明每个rule的优先级,这样就能够使得你想要的一般性概念的rule先被匹配执行。
    D.在使用ruleflow-group 的时候要注意使用lock-on-active true 关键字在每个rule。这样可以避免一旦有rule被触发,不会造成循环匹配执行。
    E.如果在LHS部分,需要调用某个方法来返回真、假值作为判断的一个条件,那么可以用eval函数。
    如,eval(pattern.matched(5,$line.getCurrLine()))
    其中,pattern是某个加入到workingmemory中的一个实例。matched是这个实例所代表类的一个方法。它返回boolean类型。
   
  (3)Drools规则引擎的使用感受
   
总之,Drools还是一个很不错的开源规则引擎。现在v4.0以上的版本已经比以前的版本在速度上有了很大的提升。可以作为我们一般应用程序系统的中间件产品(那些规则不是很经常改变的系统,已经非流程类规则)。但是,这其中还是需要一些额外的effort来学习它的使用文档以及整体架构,有一定的学习曲线。
  
    最后,我想一个较好的对于技术使用的practice就是:首先知道它能为你做什么,它最好的应用领域,然后再去深入。
   
    (PS:如果谁有使用Drools的问题,可以联系我!一起讨论!)

     
    

posted @ 2008-11-04 14:19 Jeffrey Feng 阅读(13571) | 评论 (13)编辑 收藏

Db2 catalog(编目)(转)

在DB2数据库中,编目(catalog)这个单词很难理解,我自己当初在学习 DB2的时候也常常被这个编目搞的很不明白,直到现在我个人也感觉到DB2中编目(catalog)这个术语用的不是很好,具体来说编目有编目节点,编目 数据库等如果要理解编目我先简单讲一下DB2数据库的体系结构,在DB2数据库中最大的概念是系统(节点)也就是主机,下面是实例,实例下面是数据库,然 后是表空间,然后是数据库对象。现在假设你有一个数据库服务器在p570的机器上,你有一个客户端在windows,linux或任何平台上,你现在想建 立一个客户端到服务器端的连接,具体步骤是什么呢?
第一步:
你必须要在客户端的机器上能够把远程的服务器能够识别出来,这个具体如何来做呢?Oracle中可以用SQL*NET配置,SYBASE中用OPEN CLIENT;而在DB2使用的编目(catalog)方式,具体来说就是通过编目把远程的服务器写在本地客户端的一个文件中:
db2 catalog tcpip node p570 remote 172.10.10.10 server 50000
在上面的这条命令中p570是一个节点名(在一个机器上必须是唯一的),remote后面是服务器的IP地址,server是远程服务器上实例对应的端口号
DB2通过这种方式在本地的SQLNODIR文件中把远程服务器的信息记录下来
所以编目节点其实就是把远程服务器映射到本地,通过SQLNODIR中的记录能够找到远程服务器和实例,类似指向远程服务器和实例的地址指针
第二步:
当把远程的服务器IP地址,实例编目下来后,第二步应该把该实例下的数据库编目到本地
db2 catalog db REMOTEDB at node p570
在这条命令中,REMOTEDB是远程实例下的数据库,p570是我们在第一步中编目的节点名
这条命令执行后会在本地SQLDBDIR文件中记录远程数据库的信息,这这里编目数据库可以理解为把远程服务器实例下的数据库映射到本地为一个别名
=========================
上面是客户端和服务器不在同一台机器上,是通过编目节点,编目数据库来实现客户端连接到服务器上数据库的目的,如果是连接在同一台机器上,那么这时候不要 显示的编目节点,但是在服务器上当我们创建一个实例的时候,有一个隐含的把实例在本地编目的过程,假设在p570上创建一个实例名为db2inst1,其 实有一个隐含的
db2 catalog local node db2inst1 instance db2inst1 system p570 ostype aix的步骤,
同样当你在db2inst1下创建一个数据库MYDB的时候,有一个隐含的编目(catalog)数据库的步骤:
db2 catalog db mydb at node db2inst1的步骤
至此你可以这样理解编目(catalog),编目就是在本地或远程建立客户端到服务器的数据库连接的目的,他类似Oracle数据库中的通过 SQL*NET或netca配置客户端到服务器的连接;类似SYBASE中的OPEN CLIENT;类似informix中Iconnect

http://blog.csdn.net/fxxxgxxx/archive/2007/08/27/1760999.aspx

posted @ 2008-10-23 16:50 Jeffrey Feng 阅读(912) | 评论 (0)编辑 收藏

Eclipse 插件开发中的 classnotfound 问题(转载)

目的Eclipse插件开发中,经常要引用第三方包或者是引用其他插件中的类,由于插件开发环境引用类路径的设置和运行平台引用类路径的设置不同,经常导致开发过程OK,一旦运行则出现NoClassDefFoundError的问题。本文的目的是全面分析各种情况下类路径的设置,以避免这个问题的出现。

 

说明Jar包和类路径实际上是一个概念,比如类com.bbebfe.Test.class打包为test.jar包,添加类引用就直接添加test.jar包。而如果是添加类文件路径,则添加包目录的上级目录,比如lib/com/bbebfe/Test.class,则添加lib文件夹,而不是com文件夹。在此后的例子中都只说明Jar包的形式。

 

分析Eclipse插件开发对于Jar包的引用主要有三种原因:

1. 插件引用第三方包(普通的jar包或者类文件,不是插件)。

a)        开发环境引用配置,在prject -> properties -> Java build path中设置。

b)        运行环境引用配置,在plugin manifest编辑器的Runtime选项卡下的classpath中添加tset.jar包的引用(在MANIFEST.MF中表现为Bundle-ClassPath: lib/test.jar, plugin.xml表现为<runtime>节下的引用

                         i.  类文件在lib目录下,如下的设置导出lib目录下所有目录:

<runtime>

            <library name="lib/">

             <export name="*"/>

            </library>

   </runtime>

                       ii.  test.jarlib目录下:

        <runtime>

            <library name="lib/test.jar">

             <export name="*"/>

            </library>

   </runtime>

                      iii.  实际上上面的设置可以简化为:

<runtime>

            <library name="lib/"/>

   </runtime>

    或者

<runtime>

            <library name="lib/test.jar"/>

   </runtime>

       默认即导出lib目录下的所有包和jar下的所有包

       实际上,执行b)项设置后,会自动执行a)项设置,使开发环境和运行环境同时有效。

2. 插件B引用插件工程A(非Eclipse插件,而是自己另外一个插件项目中的类)

a)        首先必须将A中的B需要的类暴露(export)出来

                         i.              如果有MANIFEST.MF文件,则表现为plugin manifest编辑器中runtime节的exported packages,通过这里添加需要export的包。在manifest.mf文件中是Export-Package: com.bbebfe

                       ii.              如果只有plugin.xml,则表现为plugin manifest编辑器中runtime节的library visibilityplugin.xml文件中表现为

<runtime>

       <library>

              <export name=”com.bbebfe.*”/>

       ...

b)        B插件工程的plugin manifest编辑器中的dependencies选项卡中添加对A插件的引用(这要求运行对话框中的plugins列表的workspace plugins中必须包含A插件)。

c)         如果B工程是一个RCP工程,则必须在product编辑器的configuration选项卡中包含A插件工程。

3. 插件B引用Eclipse插件A的类。

a)        Eclipse插件中的类都是Exported,因此这步省略。

b)        B插件工程的plugin manifest编辑器中的dependencies选项卡中添加对A插件的引用(这要求preferences -> plugin development -> target目标平台必须包含A插件,且运行对话框的plugins列表中的target platform中必须选中A插件)。

 

总结:如果B插件引用的A也是一个插件,则A必须出现在B插件的plugin dependencies引用中,而不是其他地方,否则肯定会出现运行时NoClassDefFoundError问题(因此必须在plugin manifest编辑器的dependencies选项卡下进行设置)。而且只需要在这里设置的设置对开发环境和运行环境同时有效)

 

注意:还有一种情况就是开发环境没有某个包或者插件,而只在运行环境(target)中存在,此时就必须设置正确的target,然后按照正常程序添加插件引用,但此时已经不能在plugin manifestdependencies选项卡中设置(因为在开发环境找不到这个plugin),而必须在plugin.xmlMANIFEST.MF文件中手工设置。plugin只要target中存在该插件,则开发和运行也不会有问题。

posted @ 2008-10-14 10:19 Jeffrey Feng 阅读(1315) | 评论 (0)编辑 收藏

仅列出标题
共2页: 上一页 1 2