ejb查找失败与NamingException [英] ejb lookup failing with NamingException

查看:162
本文介绍了ejb查找失败与NamingException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 < ejb-ref> 
< ejb-ref-name> ejb / userManagerBean< / ejb-ref-name>
< ejb-ref-type>会话< / ejb-ref-type>
< home> gha.ywk.name.entry.ejb.usermanager.UserManagerHome< / home>
< remote>什么应该去这里??< / remote>
< / ejb-ref>

以下java代码给我NamingException:



public $ {code> public UserManager getUserManager()throws HUDException {
String ROLE_JNDI_NAME =ejb / userManagerBean;
try {
属性props = System.getProperties();
上下文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(获取EJB UserManager时发生错误+ e);
返回null;
} catch(RemoteException ex){
log.error(获取EJB UserManager时发生错误+ ex);
返回null;
} catch(CreateException ex){
log.error(获取EJB UserManager时发生错误+ ex);
返回null;
}
}

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



StackTrace(在jsight的建议之后):

 >发生异常在目标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
在com.sun.enterprise.naming.java.javaURLContextFactory .getObjectInstance(javaURLContextFactory.java:32)
在javax.naming.spi.NamingManager.getURLObject(NamingManager.java:584)
在javax.naming.spi.NamingManager.getURLContext(NamingManager.java:533 )
在javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:279)
在javax.naming.InitialContext.lookup(InitialContext.java:351)
在gov.hud.pih。 eiv.web.EjbClient.EjbClient.getUserManager(EjbClient.java:34)


解决方案

我想你w蚂蚁从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 / p>


  1. 创建家庭界面

它定义用于创建,销毁和查找本地或远程EJB对象的方法。它作为EJB对象的生命周期接口。所有家庭接口必须扩展标准接口javax.ejb.EJBHome - 如果您使用远程ejb对象 - 或javax.ejb.EJBLocalHome - 如果您正在使用本地EJB对象。

  //远程EJB对象 - 扩展javax.ejb.EJBHome 
//本地EJB对象 - 扩展javax.ejb.EJBLocalHome
public interface MyBeanRemoteHome扩展javax.ejb.EJBHome {

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

}

应用服务器将创建Home对象作为您可以获得的一种方式一个EJB对象,没有别的。



照顾以下


A会话bean的远程家庭接口必须定义一个或多个创建< METHOD>方法。
无状态会话bean必须准确地定义一个< METHOD>方法没有参数。


...


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


...



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


...


有状态会话bean的每个创建方法必须是NAMED创建< METHOD>,并且
必须匹配Init方法之一或ejbCreate< METHOD> ;会话中定义的方法
bean类。匹配的ejbCreate< METHOD>方法必须具有相同的数字和类型的参数。无状态会话bean的create方法必须被命名为创建,但不需要匹配的ejbCreate方法。







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

  //一个远程EJB对象 - 扩展javax.ejb.EJBObject 
//本地EJB对象 - 扩展javax.ejb.EJBLocalObject
public interface MyBeanRemote extends javax.ejb.EJBObject {

void doSomething()throws java.rmi.RemoteException;

}

现在请关注以下


如果您使用的是远程EJB对象,则远程接口方法必须不显示本地接口类型或本地家庭接口类型。


< blockquote>

...


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







现在我们的EJB

  public class MyBean实现javax.ejb.SessionBean {

//为何创建方法?特别看看EJB Home的详细信息(上图)
public void create(){
System.out.println(create);
}

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

}

现在请关注以下


它必须执行javax.ejb.SessionBean。它定义了四种方法,如上所示:setSessionContext,ejbRemove,ejbPassivate和ejbActivate。请注意,由于EJB规范,我们的业务界面指示:



$ b

注意我们的bean 不执行 b
$ b

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




  • 相同的名称

  • 参数的数量和类型相同,和相同的返回类型。

  • 在会话
    bean类的匹配方法的throws子句中定义的所有异常必须在该方法的throws子句中定义本地界面。



您需要根据


$ b解密一个ejb-jar.xml文件$ b

 <?xml version =1.0encoding =UTF-8?> 
< ejb-jar xmlns =http://java.sun.com/xml/ns/j2eexmlns:xsi =http://www.w3.org/2001/XMLSchema-instancexsi :schemaLocation =http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsdversion =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

  //或@Local 
//您不能同时放置@Remote和@Local
@Remote
public interface MyBean {

void doSomething();

}

@Stateless
public class MyBeanStateless实现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. 添加/ server / default / lib(包含jar文件,以检索您的EJB)jar文件到您的Java应用程序,无论您是否使用JBoss(我不知道S中的哪个目录un application server)

  3. 执行上面的代码

现在创建另一个war PROJECT


  1. 添加我们上面创建的项目,并添加< JBOSS_HOME> / client(包含jar文件才能访问我们的EJB)。再次,我不知道Sun Application Server中的哪个目录。 Ckeck的文档。

  2. 查看全局映射地址,如答案顶部所示

并且在您的Servlet中执行以下代码,无论使用JBoss是否使用JBoss

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

属性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);

返回新的javax.naming.InitialContext(p);
}

或者以下是否使用Sun Application Server - 将文件appserv-您的类路径中的rt.jar(我不知道哪个过去包含appserv-rt.jar)在您的类路径中

  public static上下文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();

敬意,


I've added the following in my 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>

The following java code is giving me 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;
    }
}

The code is used inside the container. By that I mean that the .WAR is deployed on the server (Sun Application Server).

StackTrace (after jsight's suggestion):

>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)

解决方案

I think you want to access an EJB application (known as EJB module) from a web application in Sun Application Server, right ?

ok, let's go.

When you deploy an EJB into an application server, the application server gives it an address - known as global JNDI address - as a way you can access it (something like your address). It changes from an application server to another.

In JBoss Application Server, you can see global JNDI address (after starting it up) in the following address

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

In Sun Application Server, if you want to see global JNDI address (after starting it up), do the following

Access the admin console in the following address

http://127.0.0.1:4848/asadmin

And click JNDI browsing

If your EJB IS NOT registered right there, there is something wrong

EJB comes in two flavors: EJB 2.1 and EJB 3.0. So what is the difference ?

Well, well, well...

Let's start with EJB 2.1

  1. Create a Home interface

It defines methods for CREATING, destroying, and finding local or remote EJB objects. It acts as life cycle interfaces for the EJB objects. All home interfaces have to extend standard interface javax.ejb.EJBHome - if you a using a remote ejb object - or javax.ejb.EJBLocalHome - if you are using a local EJB object.

// 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 will create Home objects as a way you can obtain an EJB object, nothing else.

Take care of the following

A session bean’s remote home interface MUST DEFINE ONE OR MORE create<METHOD> methods. A stateless session bean MUST DEFINE exactly one <METHOD> method with no arguments.

...

throws clause MUST INCLUDE javax.ejb.CreateException

...

If your Home interface extends javax.ejb.EJBHome, throws clauses MUST INCLUDE the java.rmi.RemoteException. If it extends javax.ejb.EJBLocalHome, MUST NOT INCLUDE the java.rmi.RemoteException.

...

Each create method of a stateful session bean MUST BE NAMED create<METHOD>, and it must match one of the Init methods or ejbCreate<METHOD> methods defined in the session bean class. The matching ejbCreate<METHOD> method MUST HAVE THE SAME NUMBER AND TYPES OF ARGUMENTS. The create method for a stateless session bean MUST BE NAMED create but need not have a matching "ejbCreate" method.


Now create an business interface in order to define business logic in our EJB object

// 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;

}

Now take care of the following

If you are using a remote EJB object, remote interface methods MUST NOT EXPOSE local interface types or local home interface types.

...

If your Home interface extends javax.ejb.EJBObject, throws clauses MUST INCLUDE the java.rmi.RemoteException. If it extends javax.ejb.EJBLocalObject, MUST NOT INCLUDE the java.rmi.RemoteException.


Now our 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
    };

}

Now take care of the following

It MUST IMPLEMENTS javax.ejb.SessionBean. It defines four methods - not shown above: setSessionContext, ejbRemove, ejbPassivate, and ejbActivate.

Notice our bean DOES NOT IMPLEMENT our business interface because of EJB specification says:

For each method defined in the interface, there must be a matching method in the session bean’s class. The matching method must have:

  • The same name
  • The same number and types of arguments, and the same return type.
  • All the exceptions defined in the throws clause of the matching method of the session bean class must be defined in the throws clause of the method of the local interface.

And YOU HAVE TO DECLARE a ejb-jar.xml file according to

<?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>

If you do not have a local EJB object remove from the deployment descriptor above

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

If you do not have a remote EJB object remove from the deployment descriptor above

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

And put in META-INF directory

Our jar file will contain the following

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


Now our 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() {

    }

}

Nothing else,

In JBoss put jar file in

<JBOSS_HOME>/server/default/deploy


In Sun Application Server access (after starting it up) admin console

http://127.0.0.1:4848/asadmin

And access EJB Modules in order to deploy your ejb-jar file

As you have some problems when deploying your application in NetBeans, i suggest the following

  1. Create a simple Java library PROJECT (a simple jar without a main method)
  2. Add /server/default/lib (contains jar files in order you retrieve your EJB's) jar files to your Java application whether you are using JBoss (I do not know which directory in Sun Application Server)
  3. Implement code above

Now create another war PROJECT

  1. Add our project created just above and add <JBOSS_HOME>/client (contains jar files in order to access our EJB's). Again i do not know which directory in Sun Application Server. Ckeck out its documentation.
  2. See its global mapping address as shown in the top of the answer

And implement the following code in your Servlet or something else whether you are using 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);
}

Or the following whether you are using Sun Application Server - put the file appserv-rt.jar (I do not know which past contain appserv-rt.jar in Sun Application Server) in your classpath

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

    return new javax.naming.InitialContext();

}

In order to access your EJB in our Servlet or something else

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

myBean.doSomething();

regards,

这篇关于ejb查找失败与NamingException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆