Java ejb查找失败,出现NamingException
我在web.xml中添加了以下内容:Java ejb查找失败,出现NamingException,java,ejb,jndi,Java,Ejb,Jndi,我在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>
<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>
代码在容器内使用。我的意思是.WAR部署在服务器(Sun应用服务器)上
StackTrace(根据jsight的建议):
>目标VM中发生异常:com.sun.enterprise.naming.java.javaURLContext。(Ljava/util/Hashtable;Lcom/sun/enterprise/naming/NamingManagerImpl;)V
java.lang.NoSuchMethodError:com.sun.enterprise.naming.java.javaURLContext.(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.GetUrlOrDefaultiniticTx(InitialContext.java:279)
在javax.naming.InitialContext.lookup(InitialContext.java:351)中
网址:gov.hud.pih.eiv.web.EjbClient.EjbClient.getUserManager(EjbClient.java:34)
首先,修复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>
示例EJB
菜豆
一场
com.SampleHome
com.Sample
然后,关于java.lang.NoSuchMethodError
,Sean是对的,您在NetBeans内部使用的应用程序服务器“客户端库”的版本与应用程序服务器版本(服务器端)不匹配。但是,我不能确切地告诉您需要对齐哪些JAR,请参阅Sun Application Server文档
PS:这不是问题的直接答案,但我认为在使用调用
System.getProperties()
的结果创建初始上下文时,您当前没有传递任何有用的属性,这些属性对定义上下文环境(例如初始上下文工厂)没有任何帮助。有关更多详细信息,请参阅javadocs。最后两个答案都是正确的,因为它们是您需要更改/修复的内容。但是您看到的NoSuchMethodError不是源于代码,也不是源于试图查找代码的东西(我认为,如果是这种情况,会产生某种NoClassDefFoundException)。这看起来更像是容器提供的JNDI提供程序的不兼容版本,以及Java库中的JNDI实现所需要的。这是一个相当模糊的答案,但是,可以想象,这是可以解决的,可能需要升级您的应用程序服务器,并确保您不会在应用程序中部署与JNDI相关的基础结构类的过时副本,这可能会造成干扰。我认为您希望访问EJB应用程序(称为EJB模块)来自Sun application Server中的web应用程序,对吗
好的,我们走吧
当您将EJB部署到应用程序服务器中时,应用程序服务器会给它一个地址(称为全局JNDI地址),作为访问它的方式(类似于您的地址)。它从一个应用服务器更改为另一个应用服务器
在JBossApplicationServer中,您可以在以下地址中看到全局JNDI地址(启动后)
http://127.0.0.1:8080/jmx-console/HtmlAdaptor
http://127.0.0.1:4848/asadmin
在Sun Application Server中,如果要查看全局JNDI地址(启动后),请执行以下操作
/META-INF/ejb-jar.xml
br.com.MyBean.class
br.com.MyBeanRemote.class
br.com.MyBeanRemoteHome.class
通过以下地址访问管理控制台
http://127.0.0.1:8080/jmx-console/HtmlAdaptor
http://127.0.0.1:4848/asadmin
然后单击JNDI浏览
如果您的EJB没有在那里注册,则说明有问题
EJB有两种风格:EJB2.1和EJB3.0。那么有什么区别呢
好吧,好吧,好吧
让我们从EJB2.1开始
// 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;
}
应用服务器将创建主对象,作为获取EJB对象的一种方式,而不是其他方式
注意以下几点
/META-INF/ejb-jar.xml
br.com.MyBean.class
br.com.MyBeanRemote.class
br.com.MyBeanRemoteHome.class
会话bean的远程主接口必须定义一个或多个create方法。
无状态会话bean必须只定义一个没有参数的方法
throws子句必须包含javax.ejb.CreateException
如果您的主接口扩展了javax.ejb.EJBHome,则throws子句必须包含java.rmi.RemoteException。如果它扩展了javax.ejb.EJBLocalHome,则不能包含java.rmi.RemoteException
有状态会话bean的每个create方法必须命名为create,并且
必须与会话中定义的Init方法或ejbCreate方法之一匹配
bean类。匹配的ejbCreate方法必须具有相同数量和类型的参数。无状态会话bean的create方法必须命名为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;
}
现在注意以下几点
/META-INF/ejb-jar.xml
br.com.MyBean.class
br.com.MyBeanRemote.class
br.com.MyBeanRemoteHome.class
如果您使用的是远程EJB对象,则远程接口方法不得公开本地接口类型或本地主接口类型
如果您的主接口扩展了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
};
}
现在注意以下几点
/META-INF/ejb-jar.xml
br.com.MyBean.class
br.com.MyBeanRemote.class
br.com.MyBeanRemoteHome.class
它必须实现javax.ejb.SessionBean。它定义了四种方法——上面没有显示:setSessionContext、ejbRemove、ejbPassivate和ejbActivate
请注意,我们的bean没有实现我们的业务接口,因为EJB规范说:
对于接口中定义的每个方法,会话bean的类中必须有一个匹配的方法。匹配方法必须具有:
- 同名
- 相同数量和类型的参数,以及相同的返回类型
- 所有例外情况都已定义
// 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_HOME>/server/default/deploy
http://127.0.0.1:4848/asadmin
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); }
public static Context getInitialContext() throws javax.naming.NamingException { return new javax.naming.InitialContext(); }
MyBeanRemote myBean = (MyBeanRemote) getInitialContext().lookup(<PUT_EJB_GLOBAL_ADDRESS_RIGHT_HERE>); myBean.doSomething();