DANCE WITH JAVA

开发出高质量的系统

常用链接

统计

积分与排名

好友之家

最新评论

走近EJB Jboss 下 Hello World

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

首先是Hello World的代码,很简单就几个接口
1,远程接口
package eg;

import java.rmi.RemoteException;
import javax.ejb.EJBObject;

public interface Hello extends EJBObject {
    
public String hello() throws RemoteException;
}

2,企业Bean
package eg;

import java.rmi.RemoteException;

import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

public class HelloBean implements SessionBean {
    
private SessionContext ctx;

    
public void ejbActivate() throws EJBException, RemoteException {
        
// TODO Auto-generated method stub

    }


    
public void ejbPassivate() throws EJBException, RemoteException {
        
// TODO Auto-generated method stub

    }


    
public void ejbCreate() throws javax.ejb.CreateException {
        
    }


    
public void ejbRemove() throws EJBException, RemoteException {
        
// TODO Auto-generated method stub

    }


    
public void setSessionContext(SessionContext ctx) throws EJBException,
            RemoteException 
{
        
this.ctx = ctx;
    }


    
public String hello() {
        System.out.println(
"hello");
        
return "Hello World";
    }


}

3,Home接口
package eg;

import java.rmi.RemoteException;

import javax.ejb.CreateException;
import javax.ejb.EJBHome;

public interface HelloHome extends EJBHome {
    Hello create() 
throws RemoteException,CreateException;
}

4,用来调用的Client类
package eg;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

public class HelloClient {

    
public static void main(String[] args) throws Exception {
        Hashtable env 
= new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
        env.put(Context.PROVIDER_URL, 
"localhost:1099");
        env.put(
"java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
         
        Context ctx 
= new InitialContext(env);
        Object obj 
= ctx.lookup("Hello");
        HelloHome home 
= (HelloHome) PortableRemoteObject.narrow(obj,
                HelloHome.
class);
        Hello hello 
= home.create();
        System.out.println(hello.hello());
        hello.remove();

    }


}

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

import javax.ejb.EJBLocalObject;

public interface HelloLocal extends EJBLocalObject {
    
public String hello();
}

package eg;

import javax.ejb.CreateException;
import javax.ejb.EJBLocalHome;

public interface HelloLocalHome extends EJBLocalHome {
    HelloLocal create() 
throws CreateException;
}

这两个接口是用来本地调用的,这个解释明白它的意思,但还是不知道如何才能实现这个本地调用,了解的人给个提示,如何才能在代码中模拟出使用到这两个接口的情况。或者说模拟出使用本地接口和远程接口的区别?
疑问二:为什么企业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 部署调试也会变的方便.



posted on 2007-03-05 20:02 dreamstone 阅读(5720) 评论(3)  编辑  收藏 所属分类: jdk相关

评论

# re: 走近EJB Jboss 下 Hello World[未登录] 2007-03-05 22:01 ronghai

你做的是ejb的哪个版本ejb3.0?  回复  更多评论   

# re: 走近EJB Jboss 下 Hello World 2007-03-05 22:21 我为J狂

@ronghai
当然是EJB2.0了,因为在所有的EJB3.0规范中定义的EJB,都不必实现Home接口,而且也不用写部署描述文件。如果楼主是刚刚学习EJB,建议楼主学习EJB3.0。  回复  更多评论   

# re: 走近EJB Jboss 下 Hello World 2007-03-05 23:24 dreamstone

恩,是2.0,平时的项目开发中很少用到EJB,学习一下用于备用吧。对于EJB熟悉的帮忙回答一下文中的一些疑问,谢谢了。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: