走近EJB Jboss 下 Hello World

每次学习一些新的东西都是从Hello  World开始,这里感叹一下。本来认为Hello World这样的东西应该不必要再写,只想发两句牢骚,转几个链接了事,但接触下来,发现网上的Hello World因为转载太多,造成基本上都是不能用的版本.或多或少存在这样那样的问题,让一个初学者去调试错误是好事,也是坏事,好事是可以锻炼一下,坏事是容易打消积极性,呵呵。这里给出一个Hello World的例子和一些疑问.

首先是Hello World的代码,很简单就几个接口
1,远程接口
None.gif package  eg;
None.gif
None.gif
import  java.rmi.RemoteException;
None.gif
import  javax.ejb.EJBObject;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   interface  Hello  extends  EJBObject  dot.gif {
InBlock.gif    
public String hello() throws RemoteException;
ExpandedBlockEnd.gif}

None.gif
2,企业Bean
None.gif package  eg;
None.gif
None.gif
import  java.rmi.RemoteException;
None.gif
None.gif
import  javax.ejb.EJBException;
None.gif
import  javax.ejb.SessionBean;
None.gif
import  javax.ejb.SessionContext;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   class  HelloBean  implements  SessionBean  dot.gif {
InBlock.gif    
private SessionContext ctx;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public void ejbActivate() throws EJBException, RemoteException dot.gif{
InBlock.gif        
// TODO Auto-generated method stub
InBlock.gif

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public void ejbPassivate() throws EJBException, RemoteException dot.gif{
InBlock.gif        
// TODO Auto-generated method stub
InBlock.gif

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public void ejbCreate() throws javax.ejb.CreateException dot.gif{
InBlock.gif        
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public void ejbRemove() throws EJBException, RemoteException dot.gif{
InBlock.gif        
// TODO Auto-generated method stub
InBlock.gif

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
public void setSessionContext(SessionContext ctx) throws EJBException,
ExpandedSubBlockStart.gifContractedSubBlock.gif            RemoteException 
dot.gif{
InBlock.gif        
this.ctx = ctx;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public String hello() dot.gif{
InBlock.gif        System.out.println(
"hello");
InBlock.gif        
return "Hello World";
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

None.gif
3,Home接口
None.gif package  eg;
None.gif
None.gif
import  java.rmi.RemoteException;
None.gif
None.gif
import  javax.ejb.CreateException;
None.gif
import  javax.ejb.EJBHome;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   interface  HelloHome  extends  EJBHome  dot.gif {
InBlock.gif    Hello create() 
throws RemoteException,CreateException;
ExpandedBlockEnd.gif}

None.gif
4,用来调用的Client类
None.gif package  eg;
None.gif
None.gif
import  java.util.Hashtable;
None.gif
None.gif
import  javax.naming.Context;
None.gif
import  javax.naming.InitialContext;
None.gif
import  javax.rmi.PortableRemoteObject;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   class  HelloClient  dot.gif {
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public static void main(String[] args) throws Exception dot.gif{
InBlock.gif        Hashtable env 
= new Hashtable();
InBlock.gif        env.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
InBlock.gif        env.put(Context.PROVIDER_URL, 
"localhost:1099");
InBlock.gif        env.put(
"java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
InBlock.gif         
InBlock.gif        Context ctx 
= new InitialContext(env);
InBlock.gif        Object obj 
= ctx.lookup("Hello");
InBlock.gif        HelloHome home 
= (HelloHome) PortableRemoteObject.narrow(obj,
InBlock.gif                HelloHome.
class);
InBlock.gif        Hello hello 
= home.create();
InBlock.gif        System.out.println(hello.hello());
InBlock.gif        hello.remove();
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

None.gif
ejb-jar.xml文件
None.gif <? xml version = " 1.0 "  encoding = " UTF-8 " ?>
None.gif
<! DOCTYPE ejb - jar PUBLIC  " -//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN "   " http://java.sun.com/dtd/ejb-jar_2_0.dtd " >
None.gif
< ejb - jar >
None.gif
< description > this  is ejb helloworld </ description >
None.gif
< display - name > HelloBean </ display - name >
None.gif
< enterprise - beans >
None.gif    
< session >
None.gif        
< display - name > Hello </ display - name >
None.gif        
< ejb - name > Hello </ ejb - name >
None.gif        
< home > eg.HelloHome </ home >
None.gif        
< remote > eg.Hello </ remote >
           <!--
None.gif        
< local - home > eg.HelloLocalHome </ local - home >
None.gif        
< local > eg.HelloLocal </ local >
            -->
None.gif        
< ejb - class > eg.HelloBean </ ejb - class >
None.gif        
< session - type > Stateless </ session - type >
None.gif        
< transaction - type > Container </ transaction - type >
None.gif    
</ session >
None.gif
</ enterprise - beans >
None.gif
</ ejb - jar >
上边代码下载链接 http://www.blogjava.net/Files/dreamstone/ejb.rar
疑问一:细心的人会发现我的ejb-jar.xml中注释掉了两行,这两行对应两个本地接口
None.gif package  eg;
None.gif
None.gif
import  javax.ejb.EJBLocalObject;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   interface  HelloLocal  extends  EJBLocalObject  dot.gif {
InBlock.gif    
public String hello();
ExpandedBlockEnd.gif}

None.gif
None.gif package  eg;
None.gif
None.gif
import  javax.ejb.CreateException;
None.gif
import  javax.ejb.EJBLocalHome;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
public   interface  HelloLocalHome  extends  EJBLocalHome  dot.gif {
InBlock.gif    HelloLocal create() 
throws CreateException;
ExpandedBlockEnd.gif}

None.gif
这两个接口是用来本地调用的,这个解释明白它的意思,但还是不知道如何才能实现这个本地调用,了解的人给个提示,如何才能在代码中模拟出使用到这两个接口的情况。或者说模拟出使用本地接口和远程接口的区别?
疑问二:为什么企业Bean类不实现组建接口(既不实现远程接口也不实现本地接口),毕竟组建接口定义了企业Bean所有的业务方法,如果实现了,可以保证编译期Check
答案:这个答案是<<精通Ejb>>一书中给出的解释:

理由一:组件接口继承于Sun定义的标准接口,比如javax.ejb.EJBObject和javax.ejb.EJBLocalObject。这些超级接口为客户定义了其它方法。因此如果企业Bean类实现组件接口,则企业Bean类将需要为这些方法提供空的实现,显然,在企业Bean类中不需要这些方法

理由二:
假定企业Bean (A)需要调用其它企业Bean(B)的方法,并且,如果需要传递当前企业Bean(A)的引用给B的方法(类似于Java中的this参数)。在Ejb中,如何传递和处理这种情形?
请记住,所有的Ejb客户都是调用Ejb对象而不是企业Bean类实例本身,因此如果A调用B,开发者必须将A的Ejb对象引用(而不是对A的引用)传递给B,B将操作A的EJB对象,而不是A中企业Bean实例本身,对于A而言,B是它的客户,同所有的EJB客户一样,必须通过EJB对象调用企业Bean类实例。
而且如果企业Bean类实现了EJB组件的远程接口将存在潜在的危险,开发者可能不小心将企业Bean类的实例本身的引用传递,而不是EJB对象的引用,犹豫企业Bean类同EJB对象实现了同一接口,似的开发者能够使用this参数,而实现对企业Bean本身的引用。这太不可思议了。
看完这段解释,朦胧的懂了为什么不这么做,但是对这么作带来的后果还是不是很清楚,有经验的给说说.谢谢.

另外部署不说了,看这里吧 http://www.uml.org.cn/j2ee/200702141.asp

如果调用Client的时候抛出这个异常:
Exception in thread "main" javax.naming.NoInitialContextException: Cannot instantiate class: org.jnp.interfaces.NamingContextFactory [Root exception is java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory]
 at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:657)
 at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:247)
 at javax.naming.InitialContext.init(InitialContext.java:223)
 at javax.naming.InitialContext.<init>(InitialContext.java:197)
 at eg.HelloClient.main(HelloClient.java:17)
Caused by: java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory
 at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
 at java.security.AccessController.doPrivileged(Native Method)
 at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
 at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
 at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
 at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
 at java.lang.Class.forName0(Native Method)
 at java.lang.Class.forName(Class.java:242)
 at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:42)
 at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:654)
 ... 4 more

把Jboss Client目录下的一些类库加进来就好了

最后提供一个简单的做法:
Eclipse+Myeclipse
新建EJB工程-->新建SessionBean,名字叫HelloBean ,更改里边的业务方法
然后选择工程的属性-->Myeclipse xDoclet -->add Standard -->standard EJB -->确定
右键工程-->Myeclipse-->run xDoclet,看看是不是和上边的差不多,什么都有了,不过他的结构更好一点,借助工具能更快捷的完成任务。不过建议初学者还是自己手动来比较好。
借助Eclipse+Myeclipse 部署调试也会变的方便.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值