环境:MyEclipse 6.5 + Weblogic10 + windows server 2003
1、创建EJB项目:ejbdemo
2、定义HOME接口
3、定义SessionBean
4、配置ejb-jar.xml和weblogic-ejb-jar.xml文件,这两个文件需放在src/META-INF目录下
5、创建客户端测试,(注:客户端测试时,需要添加wlclient.jar)
1 定义接口:
1.1 扩展EJBObject接口
package ejbtest01; import java.rmi.RemoteException; import javax.ejb.EJBObject; public interface ConvertEjb extends EJBObject { public double getRmb(double usd)throws RemoteException; //这里的接口必须抛出RemoteException异常 ,否则找不到该方法 public String hello(String name)throws RemoteException; }
1.1 扩展 EJBHome接口
package ejbtest01; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface ConvertEjbHome extends EJBHome { public ConvertEjb create()throws CreateException,RemoteException; }
2 定义SessionBean,ejbCreate()至少要有一个
package ejbtest01; import java.rmi.RemoteException; import javax.ejb.EJBException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; public class ConvertEjbBean implements SessionBean { SessionContext sessionContext; public void ejbCreate(){ } public void ejbActivate() throws EJBException, RemoteException { // TODO Auto-generated method stub } public void ejbPassivate() throws EJBException, RemoteException { // TODO Auto-generated method stub } public void ejbRemove() throws EJBException, RemoteException { // TODO Auto-generated method stub } public void setSessionContext(SessionContext ctx) throws EJBException, RemoteException { this.sessionContext = ctx; } public double getRmb(double usd){ double rate = 6.98; double rmb = rate*usd; return rmb ; } public String hello(String name){ return "hello,"+name; } }
3 定义客户端JDK 使用1.4
3.1 定义一个工厂
package ejbtest01; import java.util.Hashtable; import javax.naming.Context; import javax.naming.InitialContext; public class EjbFactory { public static Object getEjbHome(String jndiName)throws Exception{ //连接到weblogic Hashtable map = new Hashtable(); map.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); //指定weblogic服务器的名称IP,远程调用体现在这里 map.put(Context.PROVIDER_URL, "t3://localhost:7001"); map.put(Context.SECURITY_PRINCIPAL, "weblogic"); //username map.put(Context.SECURITY_CREDENTIALS, "11111111"); //password Context context = new InitialContext(map); //根据JNDI名称查找,查到的就是Home接口 Object obj = context.lookup(jndiName); return obj; } }
4 配置ejb-jar.xml和weblogic-ejb-jar.xml
4.1 配置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> <display-name>EjbTestModule1</display-name> <enterprise-beans> <session> <display-name>myejb</display-name> <ejb-name>myejb</ejb-name> <home>ejbtest01.ConvertEjbHome</home> <remote>ejbtest01.ConvertEjb</remote> <ejb-class>ejbtest01.ConvertEjbBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> <!-- 指定ConvertEjb接口中的方法名称 <assembly-descriptor> <container-transaction> <method> <ejb-name>myejb</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> --> </ejb-jar>
4.2 配置weblogic-ejb-jar.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE weblogic-ejb-jar PUBLIC "-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN" "http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd"> <weblogic-ejb-jar> <weblogic-enterprise-bean> <ejb-name>myejb</ejb-name> <stateless-session-descriptor> <pool> <max-beans-in-free-pool>42</max-beans-in-free-pool> </pool> <stateless-clustering> <stateless-bean-is-clusterable>true</stateless-bean-is-clusterable> <stateless-bean-methods-are-idempotent>true</stateless-bean-methods-are-idempotent> </stateless-clustering> </stateless-session-descriptor> <transaction-descriptor> <trans-timeout-seconds>20</trans-timeout-seconds> </transaction-descriptor> <enable-call-by-reference>true</enable-call-by-reference> <jndi-name>jndi/myejb</jndi-name> </weblogic-enterprise-bean> <!-- 指定ConvertEjb接口中的方法 <idempotent-methods> <method> <ejb-name>ConvertEjb</ejb-name> <method-name>hello</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </method> </idempotent-methods> --> </weblogic-ejb-jar>
5、定义客户端测试:
package ejbtest01; import javax.rmi.PortableRemoteObject; public class Client { public static void main(String[] args) { try{ Object obj = EjbFactory.getEjbHome("jndi/myejb"); //ConvertEjbHome home = (ConvertEjbHome)obj;性能不好 ConvertEjbHome home = (ConvertEjbHome)PortableRemoteObject.narrow(obj, ConvertEjbHome.class); ConvertEjb remote = home.create(); double usd = 456; double rmb = remote.getRmb(usd); System.out.println("===========result: "+rmb); String ss = remote.hello(" 哈哈,EJB"); System.out.println("=====hello=="+ss); }catch(Exception e){ e.printStackTrace(); } } }
布署项目到weblogic10 , 启动weblogic,然后运行客户端,输出结果:
===========result: 3182.88
=====hello==hello, 哈哈,EJB
项目结构图:
ejb客户端调用经常出现的异常(weblogic环境)
1.EJB在weblogic下遇到的Exception:Exception in javax.naming.NameNotFoundException: While trying to lookup ''ejb.com/genuitec/trader/ejb/TraderHome''
在weblogic-ejb-jar.xml中<jndi-name>ejb/Hello</jndi-name>,配置的JNDI名称是否与Context.lookup("")中的JNDI名称一致,当前的weblogic版本是否支持开发中你所选用的ejb版本,实现类bean类是否实现了接口中制定的业务方法.
2、要注意的是,如果在运行时出现如下错误(BEA weblogic 8)
javax.naming.NoInitialContextException: Cannot instantiate class: weblogic.jndi.WLInitialContextFactory [Root exception is java.lang.ClassNotFoundException: weblogic.jndi.WLInitialContextFactory]” 为什么编译没问题了,却还是出错呢,这是网络上问得最多的问题。这是缺少"eaweblogic81serverlibwlclient.jar"文件所致。 在buildpath里加入这个包后再运行。
3、如果还是出错,显示“Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/corba/se/connection/ORBSocketFactory” 还是缺少包,这时如果你只安装有jre1.5.*,那是没有ORBSocketFactory这个类文件的。还是找个jre1.4.*吧,这个类在“jre/lib/rt.jar”包中。