MyEclipse+JBoss创建第一个EJB,部署并通过JNDI远程调用全过程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyEclipse+JBoss创建第一个EJB,部署并通过JNDI远程调用全过程相关的知识,希望对你有一定的参考价值。
在EJB3规范中,Entity Bean被摒弃了,替代之的是实体与JPA(Java Persistence API,Java 数据持久化API)作为数据持久层解决方案。现在看看EJB3的规范:
图1
关于实体与JPA规范和hibernate之间的联系本文不care,本文的目的是研究SessionBean(会话企业bean),特别是无状态(stateless)SessionBean。
第一步
在myEclipse中新建一个EJB工程:
图2
JPA支持暂时不选,Maven也不启用,直接单击Finish。
创建一个名为HelloWorld的EJB SessionBean:
右键点击src——new 选择EJB3 SessionBean,看到如下界面
注意Session Type选择Stateless(不保持客户机状态),自动创建Interface Remote(勾选后系统自动为我们创建HelloWorldRemote接口,暴露给客户机调用我们的远程方法),单击finish。
@Stateless
public class HelloWorld implements HelloWorldRemote {
}
我们看到系统给我们的函数名上面添加了注解。这种@annotation注解的方式替代了在EJB2规范中的xml配置方式,但同时也兼容XML配置方式。关于EJB还有几种@annotation注解我们以后再做讨论。
在HelloWorldRemote中我们写一个远程方法HelloEJB:
import javax.ejb.Remote;
@Remote
public interface HelloWorldRemote {
public String HelloEJB(String name);
}
control+s 一下然后发现 HelloWorld 这个实现类的类名被下滑花线标起来了,鼠标移上去,提示我们有未实现的接口方法,点第一个选项, myeclipse 直接帮我们创建该方法的模版代码,这也是先写接口 ( 当里面有很多很多方法的时候 ) 再写实现类的快速创建方法。
本文的题目是创建EJB并通过JNDI进行引用,那么在我们的实现类中,必须绑定一个JNDI名,这里我们直接通过@Stateless(mappedName=”HelloEJB”)来绑定JNDI.
package com.getcoo.service;
import javax.ejb.Stateless;
@Stateless(mappedName="HelloEJB")
public class HelloWorld implements HelloWorldRemote {
public String HelloEJB(String name) {
// TODO Auto-generated method stub
return name+",你好,欢迎访问我的EJB。";
}
}
接下来我们需要将此项目部署至jboss服务器,由于我这里myeclipse部署有点小问题,我们采用最笨拙的部署方式:
右键点击此项目,选择导出项目
图5
导出成Jar file
图6
选择以下导出路径,单击确定。
再打开jBoss控制台: localhost:8080
图7
展开图示的路径,我们发现helloEJB.jar还是没有出来,我再从右上角的add resource再添加一下(懒得找原因了),
图8
单击continue,OK 应该是部署好了
图9
图10
等status变为Success。
第二步:
还是在这个工程下创建一个test类(如果另建一个普通java工程,需要把上面的两个java文件拷贝过去,或者jar包拷过去当做lib,不然无法import):
/**
*
*/
package com.getcoo.client;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.getcoo.service.HelloWorldRemote;
/**
* @author 墨半成霜
*
*/
public class HelloEJBTest {
public void test() throws NamingException{
Context jbossCtx = getJBossInitialContext();
HelloWorldRemote myEJB =(HelloWorldRemote)jbossCtx.lookup("HelloEJB");
System.out.println("成功获得对远程EJB实例的引用,该引用实例为:"+myEJB);
System.out.println(myEJB.HelloEJB("墨半成霜"));
}
private Context getJBossInitialContext()
{
final String INIT_FACTORY="org.jnp.interfaces.NamingContextFactory";
final String SERVER_URL="localhost:1099";
Context ctx=null;
try{
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,INIT_FACTORY);
props.put(Context.PROVIDER_URL, SERVER_URL);
ctx= new InitialContext(props);
}
catch (NamingException ne){
System.err.println("不能连接JBoss Server 在:"+SERVER_URL);
ne.printStackTrace();
}
return ctx;
}
public static void main(String[] args) throws Exception
{
HelloEJBTest client= new HelloEJBTest();
client.test();
}
}
run一下:
不能连接JBoss Server 在:localhost:1099
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:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.InitialContext.<init>(InitialContext.java:197)
at com.getcoo.client.HelloEJBTest.getJBossInitialContext(HelloEJBTest.java:38)
at com.getcoo.client.HelloEJBTest.test(HelloEJBTest.java:22)
at com.getcoo.client.HelloEJBTest.main(HelloEJBTest.java:50)
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:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:46)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:654)
... 6 more
Exception in thread "main" java.lang.NullPointerException
at com.getcoo.client.HelloEJBTest.test(HelloEJBTest.java:23)
at com.getcoo.client.HelloEJBTest.main(HelloEJBTest.java:50)
Why?我仔细检查了一下,我这里没有错,如果被这一大堆错误吓懵了 立马去找错误的话,不是一个好程序员,我们要看什么呢?要找Root exception,对根源异常,往往这是问题关键。
root exception显示:
Cannot instantiate class: org.jnp.interfaces.NamingContextFactory
[Root exception is java.lang.ClassNotFoundException:
org.jnp.interfaces.NamingContextFactory]
多么清楚的异常,org.jnp.interfaces.NamingContextFactory这个类系统没找到。那么说我命我们引用了这个类,但是没在添加相关的lib。
这个类是jBoss的JNDI 命名上下文工厂类,我们不管了,直接把上个例子中添加的jBoss lib添加进来:
图11
再run一次:
成功获得对远程EJB实例的引用,该引用实例为:Proxy to jboss.j2ee:jar=helloEJB.jar,name=HelloWorld,service=EJB3 implementing [interface com.getcoo.service.HelloWorldRemote]
墨半成霜,你好,欢迎访问我的EJB。
恭喜,到这里,欢迎您踏入EJB的世界.
以上是关于MyEclipse+JBoss创建第一个EJB,部署并通过JNDI远程调用全过程的主要内容,如果未能解决你的问题,请参考以下文章
Myeclipse10, JBoss7.11 final, EJB 3.1 配置部署
3EJB3.0开发第一个无会话Bean和客户端(jboss4.2.3)
使用MyEclipse开发Java EE应用:用XDoclet创建EJB 2 Session Bean项目