ejb 查找因 NamingException 失败

2024-05-20

我在 web.xml 中添加了以下内容:

<ejb-ref>
        <ejb-ref-name>ejb/userManagerBean</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home>gha.ywk.name.entry.ejb.usermanager.UserManagerHome</home>
        <remote>what should go here??</remote>
</ejb-ref>

下面的java代码给了我NamingException:

public UserManager getUserManager () throws HUDException {
    String ROLE_JNDI_NAME = "ejb/userManagerBean";
    try {
        Properties props = System.getProperties();
        Context ctx = new InitialContext(props);
        UserManagerHome userHome = (UserManagerHome) ctx.lookup(ROLE_JNDI_NAME);
        UserManager userManager = userHome.create();
        WASSSecurity user = userManager.getUserProfile("user101", null);
        return userManager;
    } catch (NamingException e) {
        log.error("Error Occured while getting EJB UserManager" + e);
        return null;
    } catch (RemoteException ex) {
        log.error("Error Occured while getting EJB UserManager" + ex);
        return null;
    } catch (CreateException ex) {
        log.error("Error Occured while getting EJB UserManager" + ex);
        return null;
    }
}

该代码在容器内部使用。我的意思是 .WAR 部署在服务器(Sun 应用程序服务器)上。

StackTrace(根据jsight的建议):

>Exception occurred in target VM: com.sun.enterprise.naming.java.javaURLContext.<init>(Ljava/util/Hashtable;Lcom/sun/enterprise/naming/NamingManagerImpl;)V 
java.lang.NoSuchMethodError: com.sun.enterprise.naming.java.javaURLContext.<init>(Ljava/util/Hashtable;Lcom/sun/enterprise/naming/NamingManagerImpl;)V
 at com.sun.enterprise.naming.java.javaURLContextFactory.getObjectInstance(javaURLContextFactory.java:32)
 at javax.naming.spi.NamingManager.getURLObject(NamingManager.java:584)
 at javax.naming.spi.NamingManager.getURLContext(NamingManager.java:533)
 at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:279)
 at javax.naming.InitialContext.lookup(InitialContext.java:351)
 at gov.hud.pih.eiv.web.EjbClient.EjbClient.getUserManager(EjbClient.java:34)

我认为您想要从 Sun Application Server 中的 Web 应用程序访问 EJB 应用程序(称为 EJB 模块),对吧?

好了,走吧。

当您将 EJB 部署到应用程序服务器中时,应用程序服务器会为其提供一个地址(称为全局 JNDI 地址),作为您访问它的方式(类似于您的地址)。它从一个应用程序服务器更改为另一个应用程序服务器。

在JBoss应用服务器中,您可以在以下地址中看到全局JNDI地址(启动后)

http://127.0.0.1:8080/jmx-console/HtmlAdaptor

在 Sun Application Server 中,如果您想查看全局 JNDI 地址(启动后),请执行以下操作

通过以下地址访问管理控制台

http://127.0.0.1:4848/asadmin

然后点击JNDI浏览

如果您的 EJB 没有在那里注册,则有问题

EJB 有两种版本:EJB 2.1 和 EJB 3.0。那么区别是什么呢 ?

好啦好啦……

让我们从 EJB 2.1 开始

  1. 创建主页界面

它定义了创建、销毁和查找本地或远程 EJB 对象的方法。它充当 EJB 对象的生命周期接口。所有 home 接口都必须扩展标准接口 javax.ejb.EJBHome(如果您使用远程 ejb 对象)或 javax.ejb.EJBLocalHome(如果您使用本地 EJB 对象)。

// a remote EJB object - extends javax.ejb.EJBHome
// a local EJB object - extends javax.ejb.EJBLocalHome
public interface MyBeanRemoteHome extends javax.ejb.EJBHome {

    MyBeanRemote create() throws javax.ejb.CreateException, java.rmi.RemoteException;

}

应用程序服务器将创建 Home 对象作为获取 EJB 对象的一种方式,仅此而已。

请注意以下事项

会话 bean 的远程 home 接口必须定义一个或多个 create 方法。 无状态会话 bean 必须准确定义一个不带参数的 方法。

...

throws 子句必须包含 javax.ejb.CreateException

...

如果您的 Home 接口扩展了 javax.ejb.EJBHome,则 throws 子句必须包含 java.rmi.RemoteException。如果它扩展 javax.ejb.EJBLocalHome,则不得包含 java.rmi.RemoteException。

...

有状态会话 bean 的每个创建方法都必须命名为 create,并且它 必须与会话中定义的 Init 方法或 ejbCreate 方法之一匹配 豆类。匹配的 ejbCreate 方法必须具有相同数量和类型的参数。无状态会话 bean 的创建方法必须被命名create但不需要有匹配的“ejbCreate”方法。


现在创建一个业务接口以便在我们的 EJB 对象中定义业务逻辑

// a remote EJB object - extends javax.ejb.EJBObject
// a local EJB object - extends javax.ejb.EJBLocalObject
public interface MyBeanRemote extends javax.ejb.EJBObject {

    void doSomething() throws java.rmi.RemoteException;

}

现在请注意以下事项

如果您使用远程 EJB 对象,则远程接口方法不得公开本地接口类型或本地本地接口类型。

...

如果您的 Home 接口扩展了 javax.ejb.EJBObject,则 throws 子句必须包含 java.rmi.RemoteException。如果它扩展 javax.ejb.EJBLocalObject,则不得包含 java.rmi.RemoteException。


现在我们的EJB

public class MyBean implements javax.ejb.SessionBean {

    // why create method ? Take a special look at EJB Home details (above)
    public void create() {
        System.out.println("create");
    }

    public void doSomething() throws java.rmi.RemoteException {
        // some code
    };

}

现在请注意以下事项

它必须实现 javax.ejb.SessionBean。它定义了四个方法 - 上面未显示:setSessionContext、ejbRemove、ejbPassivate 和 ejbActivate。

注意我们的豆子不执行我们的业务接口,因为 EJB 规范说:

对于接口中定义的每个方法,都有必须是一个匹配方法在会话 bean 的类中。匹配方法必须有:

  • 同名
  • 相同数量和类型的参数以及相同的返回类型。
  • 会话匹配方法的 throws 子句中定义的所有异常 bean 类必须在本地接口方法的 throws 子句中定义。

并且您必须根据以下声明声明 ejb-jar.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1">
    <enterprise-beans>
        <session>
            <ejb-name>HelloWorldEJB</ejb-name>
            <home>br.com.MyBeanRemoteHome</home>
            <remote>br.com.MyBeanRemote</remote>
            <local-home>br.com.MyBeanLocalHome</local-home>
            <local>br.com.MyBeanLocal</local>
            <ejb-class>br.com.MyBean</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Container</transaction-type>
        </session>
    </enterprise-beans>
</ejb-jar>

如果您没有本地 EJB 对象,请从上面的部署描述符中删除

<local-home>br.com.MyBeanLocalHome</local-home>
<local>br.com.MyBeanLocal</local>

如果您没有远程 EJB 对象,请从上面的部署描述符中删除

<home>br.com.MyBeanRemoteHome</home>
<remote>br.com.MyBeanRemote</remote>

并放入META-INF目录下

我们的 jar 文件将包含以下内容

/META-INF/ejb-jar.xml
br.com.MyBean.class
br.com.MyBeanRemote.class
br.com.MyBeanRemoteHome.class

现在我们的EJB 3.0

// or @Local
// You can not put @Remote and @Local at the same time
@Remote
public interface MyBean {

    void doSomething();

}

@Stateless
public class MyBeanStateless implements MyBean {

    public void doSomething() {

    }

}

没有其他的,

在JBoss中放入jar文件

<JBOSS_HOME>/server/default/deploy

在 Sun Application Server 访问(启动后)管理控制台中

http://127.0.0.1:4848/asadmin

并访问 EJB 模块以部署您的 ejb-jar 文件

由于您在 NetBeans 中部署应用程序时遇到一些问题,我建议如下

  1. 创建一个简单的Java库PROJECT(一个没有main方法的简单jar)
  2. 无论您是否使用 JBoss(我不知道 Sun Application Server 中的哪个目录),都将 /server/default/lib(包含 jar 文件,以便检索 EJB)jar 文件添加到 Java 应用程序中
  3. 实现上面的代码

现在创建另一个战争项目

  1. 添加上面创建的项目并添加 /client (包含 jar 文件以便访问我们的 EJB)。我再次不知道 Sun Application Server 中的哪个目录。查看其文档。
  2. 查看其全局映射地址,如答案顶部所示

并在您的 Servlet 或其他内容中实现以下代码,无论您使用的是 JBoss

public static Context getInitialContext() throws javax.naming.NamingException {

    Properties p = new Properties();
    p.put(Context.INITIAL_CONTEXT_FACTORY,        "org.jnp.interfaces.NamingContextFactory");
    p.put(Context.URL_PKG_PREFIXES, " org.jboss.naming:org.jnp.interfaces");
    p.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");

    return new javax.naming.InitialContext(p);
}

或者以下内容,无论您使用的是 Sun Application Server - 将文件 appserv-rt.jar (我不知道 Sun Application Server 中过去包含 appserv-rt.jar )放在您的类路径中

public static Context getInitialContext() throws javax.naming.NamingException {

    return new javax.naming.InitialContext();

}

为了在我们的 Servlet 或其他东西中访问您的 EJB

MyBeanRemote myBean = (MyBeanRemote) getInitialContext().lookup(<PUT_EJB_GLOBAL_ADDRESS_RIGHT_HERE>);

myBean.doSomething();

regards,

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ejb 查找因 NamingException 失败 的相关文章

随机推荐