Monday, February 26, 2007

head first ejb(session bean)

session bean分为stateful bean与stateless bean, 主要分别为stateful bean可以保存当前服务对象的状态, 而且是每个服务对象都会有为自己服务的bean. stateless bean则不保存服务对象的状态, 只是根据服务对象所要求的操作提供服务, 可以为多个对象提供报务.

session bean要实现SessionBean, 然后加上自己的业务方法. 它是真正的业务服务的提供者(其实应当是POJO的EJB封装). 这些业务方法应该与其返回给客户的远程接口的方法名相同, 除了不能有RemoteException之外.

session bean生活在ejb容器的控制中, 处在ejb object的保护之下, 并不直接与所服务的客户进行交流. 对于一个session bean来说, 其生命周期主要由建立, 处理服务, 钝化, 激活与移除组成. stateful bean一般会完整的经历这些过程, 但对于stateless bean来说, 由于其不保存客户的状态信息, 所以没有钝化与激活这两个过程.

在客户要求某个服务后, 容器负责将对应提供服务的session bean建立. 顺序是constructor setSessionContext ejbCreate. 然后通过ejbPassivate与ejbActivate进行钝化与激活. 最后再通过ejbRemove通知bean将被移除.

容器利用setSessionContext(SessionContext sc) 方法将自己的session context传给session bean, 使其可以通过SessionContext得到自己所在容器的事务\安全\资源等环境信息. 但在这个方法时, bean实际上还没真正在容器中成为session bean, 所以在这个方法中只能将对SessionContext的引用保存下来, 留给后面的方法使用. 当然在这个方法中, bean已经可以访问环境了, 比如使用jndi, 但不能使用jndi给出的对象. 所以个人认为还不如放到ejbCreate()中再说.

容器利用ejbCreate()方法通知bean它现在成为了session bean了. 这给bean一个机会, 在这个方法中真正的引用环境来初始化自己. 但在这个方法中, 由于不是对应的业务服务, 所以无法进行CMT方法的操作. 对于stateless bean来说, 只需要一个ejbCreate()方法, 而且容器也只会调用这个方法来进行通知. 而对于stateful bean来说, 可以提供多个ejbCreate方法, 而且这个方法可以以ejbCreateXXXX的形式存在, 当然对应的home就要声明成createXXXX的形式.

对于stateful bean来说, 由于其保存了客户的信息, 所以不能同时对多客户提供服务, 如果它服务的客户在一段时间内没有要求其服务又不明确表示可以移除, 那么容器将会使用java的流机制对这个bean进行保存, 这一过程又叫钝化. 等到客户又有要求提供服务时再进行激活. 容器在进行钝化时, 会调用ejbPassivate()通知对应的bean. 而bean应当在这个方法中将其持有的不可流化的资源关闭,或使用自己的方法将其保存, 等到激活时再打开. 实际上由于容器对钝化的bean实行的是, 如果超时就将其抛弃的政策而不会调用ejbRemove, 所以在ejbPassivate时, 应当将不能被jvm的gc收集的资源关闭. 对于激活, 容器会通过ejbActivate()来通知bean, 所作的事情与ejbPassivate()相反.

容器在移除session bean时, 会调用ejbRemove(). 在这个方法里, session bean可以进行其的资源的释放工作. 而且j2ee的规范要求session bean不能有finalize方法, 所以只有这个方法可以进行让其进行这方面的工作了(其实ejbPassivate也要进行这方法的工作, 只是没这么明显而已). 但在下列情况下, 容器不会调用ejbRemove: session bean在钝化中超时, 容器崩溃, session bean的业务方法抛出了system exception(runtime exception). 这时, 资源的关闭就是你的问题了(汗, 真是规范定义者的风度啊).

如何在UBUNTU上安装EMACS23(汇总贴)

1、 如果你没有CVS的话,

sudo apt-get install cvs 用来安装cvs

2、用
cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/emacs co -r emacs-unicode-2 emacs
从cvs服务器上得到最新的emacs

3、 安装如下的包
sudo apt-get build-dep emacs21
sudo apt-get install xserver-xorg-dev
sudo apt-get install xorg-dev
sudo apt-get install libncurses5
sudo apt-get install libncurses5-dev
sudo apt-get install libidl-dev
sudo apt-get install libgtk2
.0-dev

4、 开始编译emacs啦,大家慢慢等哦
./configure --enable-font-backend --with-xft --with-freetype --with-gtk
make bootstrap
make

5、 编译完后,用 src/emacs试一下,没有问题了再运行
sudo make install

6、 好了,这下都OK啦。谢谢摘要中的两位BLOG作者,大家多多去他们那儿看看哦。

原来因为编写错误, 忘记加上两位BLOG作者的网址了, 不好意思啊, 现在加上

本文章是汇总文章,内容都是来自
http://jasonal.blogspot.com/2006/05/getting-cvs-emacs-23.html
与
http://www.dirk.sh/diary/install_emacs_23_in_ubuntu_610,因为这两个BLOG中各有自己的问题,所以再写一汇总的,一次解决掉

emacs的一些设置

想要让 emacs 显示中文,需要设置你的 ~/.Xresources 文件添加以下参数:

Emacs.Font:fontset-chinese
Emacs
.Fontset-0:-*-fixed-medium-r-*-*-14-*-*-*-c-*-fontset-chinese,
chinese-gb2312:-*-wenquanyi bitmap song-*-*-normal--*-*-*-*-*-*-iso10646-
1,
chinese-big5-
1:-*-wenquanyi bitmap song-*-*-normal--*-*-*-*-*-*-iso10646-1,
chinese-big5-
2:-*-wenquanyi bitmap song-*-*-normal--*-*-*-*-*-*-iso10646-1

同样,为了方便使用 emacs,需要设置 ~/.emacs 文件:
(global-set-key (kbd "C-SPC") 'nil)
(custom-set-variables
'
(load-home-init-file t t))
(custom-set-faces)
(setq default-major-mode 'text-mode);一打开就起用 text 模式。
(global-font-lock-mode t);语法高亮
(auto-image-file-mode t);打开图片显示功能
(fset 'yes-or-no-p 'y-or-n-p);以 y/n代表 yes/no,可能你觉得不需要,呵呵。
(column-number-mode t);显示列号
(show-paren-mode t);显示括号匹配
(display-time-mode 1);显示时间,格式如下
(setq display-time-24hr-format t)
(setq display-time-day-and-date t)
(tool-bar-mode nil);去掉那个大大的工具栏
(scroll-bar-mode nil);去掉滚动条,因为可以使用鼠标滚轮了 ^_^
(mouse-avoidance-mode 'animate);光标靠近鼠标指针时,让鼠标指针自动让开
(transient-mark-mode t);
(setq x-select-enable-clipboard t);支持emacs和外部程序的粘贴
(setq frame-title-format "DIrk@%b");在标题栏提示你目前在什么位置
(setq default-fill-column 80);默认显示 80列就换行
(setq-default make-backup-files nil);不要生成临时文件

Spring与iBATIS集成时,一对多表会出错的问题的解释

在Spring中集成iBATIS中,如果orm的对象是一对多表时,会报NullPointerException. 这是因为ibatis在上一版本时,每次调用openSession时, 都会去localSqlMapSession中查找,如果没有才会打开个新的,而且会在返回前放入 localSqlMapSession中, 所以打开都是同一个session, 这被认为是一个BUG,所以在这个版本上改为返回一个新的session.而在这个session关闭时,才会 把这个session返回给sessionPool中, 而且也没有放回localSqlMapSession中.

而在spring中,在执行时,会设置新打开的session的setUserConnection方法. 因为新的session没有进入localSqlMapSession中,所以在打开一对多的表的子表时, iBATIS从sessionPool中得到一个没有被spring设置过setUserConnection的session,从而 Transaction trans = getTransaction(session);这里没有得到缺省的连接,那么 trans = autoStartTransaction(session, autoStart, trans);代码里就会去找这个session的txManager来启动一个事务,但txManager又是null,于是就会发出 nullpoint异常了.

这时关键就是session的txManager是什么时候设置的. 我们可以看一下spring的SqlMapClientFactoryBean的代码就会发现,只有设置了它的dataSource属性时,才会去设置 session的txManager, 所以这里就可以看出在一对多表时,SqlMapClientFactoryBean的dataSource属性一定要设置, 这样能保证在一对多时才不会出问题.

head first EJB (ejb architecture)

今天主要学习了EJB的架构与session bean部分的知识.

ejb工作流程主要是这样子的: 客户首先使用JNDI得到注册的IIOP对象, 在PortableRemoteObject.narrow的得到实际的home接口的stub. 根据home接口再得到实际要使用的远程业务接口. 在请求实际的远程业务接口时, home建立了根据配置文件生成的ejb object, 再将其的stub返回给客户, 这样客户就可以进行实际的操作了. 客户操纵ejb object就好像它是真正提供服务的那个bean一样. 而实际上ejb object要使用session bean来进行具体的操作. 而ejb object是容器自动生成的一个类, 它提供了容器根据配置文件所能提供的服务.

home bean在ejb的架构中主要充当了一个标记的作用, 客户通过home bean来得到ejb object就给了ejb容器一个机会, 从配置文件中生成包装过后的ejb object来提供客户实际的服务. 所以它实际上只是一个从EJBHome接口上继承下来的接口而已, 实际生成的类是由容器来实现的.

ejb object其实是一个ejb容器根据配置文件动态生成的类, 它类似于一个aop的方法拦截器, ejb容器可以通过它在客户调用实际的业务方法时, 提供自己的服务.

session bean从SessionBean上继承下来, 是一个具体的类. 它提供了实际的业务服务, 当然最好是对实际业务POJO的包装. 它在并不直接返回给客户使用时, 而是在ejb object的身后, 通过ejb object的调用提供服务. 由于被ejb容器进行类似aop的包装, 在包装后的类中实现了客户所见的远程接口, 所以在ejb object中可以不去实现对应的远程接口, ejb容器可以通过反射来进行方法调用.


在这个架构中, home真正起到的作用大约只有减少JNDI的服务名的数量了. 因为实际上在一个ioc容器中, 根据配置文件进行包装可以通过对业务bean的aop包装来实现, 而根本不必通过home来给容器提供这个机会. 由于所有的这些都要通过EJBRemoteXXX远程接口, 而对于本地服务, 又是通过EJBLocalXXX接口. 所以对于客户来说, 远程与本地的服务所表现出来的是不一样的. 这使的客户端要明确的知道自己使用的是远程还是本地的接口. 虽然这个可以通过adapter与factory或service locator来进行封装, 但这样已经是一种麻烦了.

to be continue....

Sunday, February 25, 2007

关于Delphi7写的WebService不能被AXIS1.4解析的解决方法

工作中遇到Delphi 7写的WebService,在JBuildX上能正确的解析成Java类,但在JBuild2006与Eclipse的WTP上解析出错的问题.经比较 发现,Delphi7与JBuildX是使用axis1.0进行解析,在1.0至1.4的过程中,soap协议本身发生了变化,所以造成无法解析的问题.

解决方法是从JBuilderX上找到axis所需的
axis.jar
commons-discovery.jar
commons-logging.jar
jaxrpc.jar
wsdl4j.jar

在将其加入CLASSPATH后,直接使用命令
java org.apache.axis.wsdl.WSDL2Java 文件或网址
就可以了,具体使用可以参考apache的axis文档

在Oracle817上安装java虚拟机详细步骤

Linuxmine收集整理  作者:linux宝库 (http://www.linuxmine.com)

  在安装以前可以在ORACLE_HOME/javavm 目录下找到readme,另外注意的是所有jvm相关的sql都必须用sys as sysdba权限.
  
  先决条件:
  1:rollback segment至少100m
  2:System tablespace,所有的脚本大概要消耗130m,initjvm.sql 所产生
  的objects 消耗接近90m空间.
  3:Shared_pool_size >=50m
  4:Java_pool_size >=30m
  pool sizes 大小可以用
  select * from v$sgastat where name = 'free memory' 检定. 
  安装过程:
  1:***INITJVM.SQL*** 
  SQL>set echo on 
  SQL>spool jvminst.log 
  SQL>@/javavm/install/initjvm.sql 
  SQL>spool off 
  作用:载入初始用来支持java应用的java类包,初始化支持java和corba的名字空间的表,以及发布顶层调用的入口指针.
  支持的java类包括:
  The standard Java runtime
  Bytecode verifier and optimizer
  Java and SQLJ compilers 
  JDBC runtime
  CORBA ORB and EJB runtime
  Some additional support classes, such as DBMS_JAVA, which are 
  described in "Package DBMS_JAVA" 
  initjvm.sql 同时做以下动作:
  1:将类载入SYS schema
  2:建立这些类的同义词,使可以被所有用户访问.
  3:调整一些类的权限使支持CORBA callouts.
  4:定义一些数据库start up 和shut down触发器.
  注意:如果initjvm.sql 运行失败,在重新运行以前必须先执行rmjvm.sql,安装失败一般都是因为资源不足的问题,比如memory 和tablespace 
  2:***INITXML.SQL*** 
  SQL>set echo on 
  SQL>spool initxml.log 
  SQL>@?/oracore/admin/initxml.sql 
  SQL>spool off 
  
  主要功能:
  将xml 组件load到jserver里,可以利用plsql的接口对xlm进行扩展.
  XML Parser for PL/SQL 支持 W3C XML 1.0 规范
  3:***CATXSU.SQL*** 
  SQL>set echo on 
  SQL>spool catxsu.log 
  SQL>@?/rdbms/admin/catxsu.sql 
  SQL>spool off 
  
  主要功能:
  将XMLSQL Utility (XSU)装入数据库,主要用来做data transformation,
  将关系型的数据的SQL query result转换到xml格式,反之依然.
  ***INIT_JIS.SQL*** 
  SQL>set echo on 
  SQL>spool init_jis.log 
  SQL>@?/javavm/install/init_jis.sql 
  SQL>spool off 
  
  主要功能:
  用来安装Oracle Servlet Engine (OSE)的,OSE象一个特定的web server一样工作,servlet类通过java载入命令置入数据库,并在数据库的namespace 里注册,A servlet runner 处理HTTP 请求,publise serverlet进程,invoke serverlet 方法.
  ***JISJA.SQL*** 
  
  主要功能:
  主要用来使能JAccelerator (ncomp) for JIS,对优化性能有帮助,JServer Accelerator 通过ncomp工具将java类编译成共享库,来提高执行效率.
  ***JISAEPHC.SQL*** 
  SQL>set echo on 
  SQL>spool jisaephc.log 
  SQL>@?/javavm/install/jisaephc.sql 
  SQL>spool off 
  
  主要功能:
  OSE 安装完毕后,Adds the set of default end points to the server with hardcoded values for the admin service 
  ***INITPLGS.SQL*** 
  SQL>set echo on 
  SQL>spool initplgs.log 
  SQL>@?/rdbms/admin/initplgs.sql 
  SQL>spool off 
   
  主要功能:
  
  将PLSQL Gateway Servlet 的jar文件装入数据库,这个使plsql的存储过程可以象servelet那样运行,PL/SQL 过程可以在web上运行而无需做任何改装,
  ***INITJSP.SQL*** 
  SQL>set echo on 
  SQL>spool initjsp.log
  SQL>@?/jsp/install/initjsp.sql 
  SQL>spool off 
  
  主要功能:
  用来安装Java Server Pages (JSP) ,
  ***JSPJA.SQL*** 
  SQL>spool jspja.log 
  SQL>@?/jsp/install/jspja.sql 
  SQL>spool off 
  
  主要功能:
  用JAccelerator 来performace jsp功能组件,以native 方式编译java代码.
  ***INITPLSJ.SQL*** 
  SQL>spool initplsj.log 
  SQL>@?/rdbms/admin/initplsj.sql 
  SQL>spool off 
  
  主要功能:
  初始化plsql 的java类库
  ***INITJMS.SQL*** 
  SQL>spool initjms.log 
  SQL>@?/rdbms/admin/initjms.sql 
  SQL>spool off 
  
  主要功能:
  将AQ/JMS 载入数据库,oracle ssaging Service (JMS)提供了一组java api来支持Advanced Queuing based on the JMS standard,
  ***INITREPAPI.SQL*** 
  SQL>spool initrepapi.log 
  SQL>@?/rdbms/admin/initrepapi.sql 
  SQL>spool off 
  
  主要功能:
  This script loads RepAPI server classes and publishes the 'repapi' objects
  The RServer.class and its helper class are published in /etc namespace. RepAPI is a runtime library that enables clients to replicate data with Oracle servers. 
  ***INITSOXX.SQL*** 
  SQL>spool initsoxx.log 
  SQL>@?/rdbms/admin/initsoxx.sql 
  SQL>spool off 
  
  主要功能:
  This script loads objects, extensibility and xml related java classes into the database. 
  ***JISAEP.SQL*** 
  SQL>spool jisaep.log 
  SQL>@?/javavm/install/jisaep admin 8080 9090 
  SQL>spool off 
  
  主要功能:
  将OSE 配置成缺省的web服务,需要2个或三个参数
  1:服务名,2:TCP 端口,3: ssl端口
  -----
  如何检定安装是否成功:
  新装的数据库,即运行过catalog.sql 和 catproc.sql后,数据库里并没载入java对象,可以通过查询DBA_OBJECTS,条件是OBJECT_TYPE like 'JAVA%'来检查. 
  select count(*) from DBA_OBJECTS where OBJECT_TYPE like 'JAVA%';  This should return a count of 6785.  
  查找无效java对象
  select count(*) from DBA_OBJECTS 
  where OBJECT_TYPE like 'JAVA%' and STATUS = 'INVALID'; 
  如果数量小于第一个查询的值或第二个查询有返回,可能就需要浏览一下spool 的log,来找原因了.
  INITJVM.SQL CREATES: 
  - 
  3 functions 
  4 indexes 
  6438 java classes 
  290 java data 
  57 java resources 
  6 packages 
  1 sequence 
  6443 synonyms 
  8 tables 
  2 triggers 
  3 views 
  SQL> select count(*), object_type from dba_objects where object_type like 'JAVA%' group by object_type; 
  6438 JAVA CLASS 
  290 JAVA DATA 
  57 JAVA RESOURCE 
   
  6785 
   
  INITXML.SQL CREATES: 
  -
  2 indexes 
  272 classes 
  31 java resources 
  1 lob 
  19 packages 
  272 synonyms 
  2 tables  
  CATXSU.SQL 
  CREATES: 
  29 classes 
  30 java resources 
  3 packages 
  3 synonyms 
  INIT_JIS.SQL 
  CREATES: -- 
  12 indexes
  2384 classes
  10 java resources
  1 lob 
  13 packages
  5 sequences 
  2400 synonyms
  17 tables
  1 trigger 
  1 view 
  JISJA.SQL 
  CREATES: ------------------ 
  154 classes 
  8 java sources 
  1 procedure 
  3 tables 
  JISAEPHC.SQL
  CREATES: --
  No new objects...... 
  INITPLGS.SQL
  CREATES: -- 
  1 class
  1 synonym 
  INITJSP.SQL
  CREATES: -
  275 classes 
  2 java resources 
  275 synonyms 
  JSPJA.SQL 
  CREATES: ------------------ 
  20 classes 
  INITPLSJ.SQL
  CREATES: -- 
  2 classes 
  INITJMS.SQL CREATES: - 
  159 classes 159 synonyms 
  INITREPAPI.SQL 
  CREATES: ----
  71 classes 
  71 synonyms 
  INITSOXX.SQL 
  CREATES: --
  37 classes
  37 synonyms 
  JISAEP.SQL
  CREATES: 
  No new objects..... 
  TOTALS AFTER THE EXECUTION OF ALL SCRIPTS: 
  ---- 
  SQL>select count(*) from dba_objects
  where object_type like 'JAVA%' and owner = 'SYS'; 
  COUNT(*) ---------- 10270 
  SQL>select count(*) from dba_objects 
  where object_type like 'JAVA%' and status = 'INVALID' and owner = 'SYS'; 
  COUNT(*) ---------- 0

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1422715

Sunday, January 21, 2007

Java动态调用WebService方法

突然之间.WSDL2JAVA不能认Delphi写的WebSerice生成的WSDL了.于是才开始看看如何动态调用, 其实这里的代码都是从JBuilderX的WSDL2JAVA中自动生成的stub作参考的.

OperationDesc opd = new OperationDesc();
opd.setName("AttemperFiberPairChannel");
opd.addParameter(new QName("aStartID"), XMLType.XSD_INT, int.class,
ParameterDesc.IN, false, false);
opd.addParameter(new QName("aStartType"), XMLType.XSD_STRING, String.class,
ParameterDesc.IN, false, false);
opd.addParameter(new QName("aEndID"), XMLType.XSD_INT, int.class,
ParameterDesc.IN, false, false);
opd.addParameter(new QName("aEndType"), XMLType.XSD_STRING, String.class,
ParameterDesc.IN, false, false);
opd.setReturnType(new QName("string"));
opd.setReturnClass(String.class);
opd.setReturnQName(new QName("", "return"));

Service service = new Service();
Call call = (Call) service.createCall();
call.setOperation(opd);
call
.setTargetEndpointAddress("http://localhost/WebService/NormalResourceAttemperok/SOAP/INormalResourceAttemper");
call.setOperationName(new QName(
"urn:NormalResourceAttemperIntf-INormalResourceAttemper",
"AttemperFiberChannel"));
call
.setSOAPActionURI("urn:NormalResourceAttemperIntf-INormalResourceAttemper#AttemperFiberChannel");
Object rsl = call.invoke(new Object[]...{调用的参数});

if (rsl instanceof RemoteException) {
throw (RemoteException) rsl;
} else {
将其转化为你要的对象.这里就是String对象.
}


里面的urn部分可以从wsdl里得到, 返回的对象可能是远程异常哦.