EJB查找与NamingException的失败(ejb lookup failing with N

2019-07-19 10:55发布

我已在我的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部署在服务器(太阳应用服务器)上。

栈跟踪(后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)

Answer 1:

我想你想在太阳的应用服务器来访问从Web应用程序EJB应用程序(称为EJB模块),对不对?

好的,我们走吧。

当部署EJB到应用服务器,应用服务器为它指定一个地址 - 被称为全球JNDI地址 - 作为一种方法可以访问它(像您的地址)。 它从应用服务器到另一个变化。

在JBoss应用服务器,你可以看到全局JNDI地址在下面的地址(开始起来后)

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

在孙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;

}

Application Server将创建主页对象的一种方式,你可以得到一个EJB对象,没有别的。

看看下面的护理

会话bean的远程home接口必须定义一个或多个create <METHOD>方法。 无状态会话bean必须定义一个<METHOD>方法没有参数。

...

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

...

如果你的主接口扩展javax.ejb.EJBHome,抛出子句必须包括java.rmi.RemoteException异常。 若延续javax.ejb.EJBLocalHome,不能包含java.rmi.RemoteException异常。

...

每创建一个状态会话bean的方法必须命名为创建<METHOD>,并且它必须匹配在会话bean类中定义的初始化方法或的ejbCreate <METHOD>方法之一。 匹配的ejbCreate <METHOD>方法必须有争论的相同数量和类型。 对于无状态会话bean创建方法必须命名为创建 ,但不必有匹配“的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,抛出子句必须包括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的类中的匹配方法 。 匹配方法必须具有:

  • 相同的名称
  • 相同数量和类型的参数,和相同的返回类型。
  • 会话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

在太阳的应用服务器访问管理控制台(开始起来后)

http://127.0.0.1:4848/asadmin

而为了部署ejb-jar文件访问EJB模块

当你部署在NetBeans应用程序时有一些问题,我建议以下

  1. 创建一个简单的Java库项目(一个简单的罐子没有一个主要方法)
  2. 添加/服务器/默认/ lib目录(包含jar文件,以便您找回您的EJB的)jar文件到您的Java应用程序,无论您是使用JBoss(我不知道在太阳应用服务器的目录)
  3. 执行上面的代码

现在,创建另一个项目战争

  1. 加入我们的项目创建的正上方,并添加<JBOSS_HOME> /客户端(包含jar文件,以便访问我们的EJB的)。 再次,我不知道在太阳应用服务器的目录。 Ckeck出它的文档。
  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应用服务器 - 将文件的appserv-rt.jar的(我不知道是哪个过去包含在Sun Application服务器的appserv-rt.jar中)在类路径

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

    return new javax.naming.InitialContext();

}

为了访问EJB在我们的Servlet或别的东西,

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

myBean.doSomething();

问候,



Answer 2:

也许查找字符串实际上应该是: “Java的:comp / env的/ EJB / userManagerBean”?



Answer 3:

最后两个答案都正确的,因为它们是你需要改变/修复的东西。 但是你看到的NoSuchMethodError是不是从你的代码,也没有从事物试图找到你的代码(会产生某种NoClassDefFoundException的,我认为,是这一情况)。 这看起来更像是由容器提供的JNDI供应商,并在Java库中的JNDI实现想要什么的不兼容版本。 这是一个相当模糊的回答,但是,会想象它是可能升级的应用程序服务器,并确保你没有部署与应用到JNDI相关的基础设施类,可能会干扰的可能是陈旧的副本可解。



Answer 4:

首先,解决您的web.xml,并在其中添加远程接口:

<ejb-ref>
  <description>Sample EJB</description>
  <ejb-ref-name>SampleBean</ejb-ref-name>
  <ejb-ref-type>Session</ejb-ref-type>
  <home>com.SampleHome</home>
  <remote>com.Sample</remote> <!-- the remote interface goes here -->
</ejb-ref>

然后,关于java.lang.NoSuchMethodError ,肖恩是对的,你有应用服务器“客户端库”的版本之间不匹配您正在使用的内部NetBeans和应用服务器版本(服务器端)。 我不能告诉你到底是哪罐子,你需要对齐,虽然,请参阅Sun Application Server文档。

PS:这是不是直接回答这个问题,但我不认为创建与调用的结果初始上下文,当你路过目前任何有用的属性System.getProperties()有什么在这些性能有帮助定义一个上下文的环境(例如,初始上下文工厂)。 请参阅InitialContext的 javadoc,了解更多详情。



文章来源: ejb lookup failing with NamingException
标签: java ejb jndi