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,看到如下界面

图3

注意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 直接帮我们创建该方法的模版代码,这也是先写接口 ( 当里面有很多很多方法的时候 ) 再写实现类的快速创建方法。

图4

本文的题目是创建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的世界.

时间: 2024-11-09 20:07:18

MyEclipse+JBoss创建第一个EJB,部署并通过JNDI远程调用全过程的相关文章

EJB学习(二)——使用Eclipse+JBOSS创建第一个EJB项目

    1.环境配置 ·Eclipse Luna Service Release 1 (4.4.1) ·JBOSS AS 5.0 ·Java 1.8.0_25     2.创建一个EJB项目 依次点击File → New → EJB Project,填写项目名称如下: 然后点击Next → Finish; 选中EJB项目下的ejbModule文件夹,右击→ New→ Session Bean(EJB 3.X),创建一个Session Bean. HelloWrold接口: package com

JBoss 7 里一个EJB依赖其他jar的几种方式

JBoss 7 与之前的版本有了巨大的变化,最核心的类的加载方式变了,有点类似OSGI那样搞起来了分模块的类加载方式,而不是以前的分层类加载.按以前的类加载方式,在加载树底下的那些类,总是能看到父节点已经加载过的类.但是分模块加载后就不一样了. 碰到的第一个问题就是,到哪里存放项目以来的那些第三方库 (不只是第三方库,同一个项目里也会有一些jar是需要在不同ejb间共享的).以前的方式是放在common/lib或者server/{部署模块}/lib下面,这样所有的部署模块下的应用都可以访问到这些

ejb学习1-helloword,ejb远程调用

环境 win7 myeclipse10 jboss4.0.5 创建第一个ejb项目 1. new EJB project 2.创建一个 sessionbean 接口 3.编写ejb接口 package com.mo.ejb; import javax.ejb.Stateless; @Stateless public interface HelloWorld { String sayHello(String name); } 4.实现接口 package com.mo.ejb; public cl

远程调用jboss as 7上部署的ejb出现No EJB receiver available for handling 异常

昨天倒腾了一天终于配置好了jboss as 7的域,今天又倒腾了一整天在上面部署了个EJB,然后试了一个利用JNDI来进行远程调用.下面记录一下过程中那些乱七八糟的问题: 首先是这个jboss-client.properties文件,各个属性值的含义可以从jboss的官方文档上得到解释https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI 1 endpoint.name=

实验四十七微软应用程序虚拟化之二APP-V Sequencer 5.1服务器部署和创建第一个Office虚拟应用程序包

 实验四十七微软应用程序虚拟化之二APP-V Sequencer 5.1服务器部署和创建第一个Office虚拟应用程序包 APP-V Sequencer用于监视和捕获应用程序安装以创建虚拟应用程序包.输出包含应用程序图标..osd 文件(包含程序包定义信息).程序包清单文件,以及 .sft 文件(包含应用程序的内容文件). 说明: 环境基于实验四十六,准备一台Windows Server 2012的虚拟机名为APP-VSequencer并且加入域kkfloat.com,然后关闭UAC功能 1登录

使用 maven:archetype 创建JSF2 + EJB3.1 + JPA2项目骨架并在JBoss WildFly 8.1上部署

执行以下命令创建项目骨架: mvn archetype:generate -DarchetypeGroupId=org.jboss.spec.archetypes -DarchetypeArtifactId=jboss-javaee6-webapp-ear-archetype -DarchetypeVersion=7.1.1.Final -DgroupId={你的groupId} -DartifactId={你的artifactId} -Dversion=1.0-SNAPSHOT 项目生成完毕后

spring (由Rod Johnson创建的一个开源框架)

你可能正在想"Spring不过是另外一个的framework".当已经有许多开放源代码(和专有)J2EEframework时,我们为什么还需要Spring Framework? Spring是独特的,因为若干个原因: 它定位的领域是许多其他流行的framework没有的.Spring致力于提供一种方法管理你的业务对象. Spring是全面的和模块化的.Spring有分层的体系结构,这意味着你能选择使用它孤立的任何部分,它的架构仍然是内在稳定的.因此从你的学习中,你可得到最大的价值.例如

MyEclipse下创建的项目导入到Eclipse中详细的图文配置方法

一.情景再现. 有些人比较喜欢用Myeclipse开发,有些人却比较喜欢用eclipse开发.但是其中有一个问题,Myeclipse里面的项目导入的时候出现了一个小小的问题. 如下: 二.说明问题 导入的项目不仅包显示在外面,而且不能部署到tomcat中. 那我们需要如何的配置呢? 三.处理问题. 1.导入在MyEclipse下创建的项目 2.把项目变成Web项目,在项目上右键-->Properties-->选择Project Facets. 3. 选中红线框住的两项(java和Dynamic

Ejb远程调用-jboss服务器调用服务器-Bean调用Bean

英文参考地址 https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project 要解决的问题 公司的底层架构中的Ejb的远程调用通过Controller调用的Bean,所有现在存在的问题就是业务逻辑都写到了Controller,有一些业务得不到复用,方法得不到复用.分布式事务无法控制等等,所以咱们急需把业务写到Bean的实现里面,