我已在我的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)
我想你想在太阳的应用服务器来访问从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
- 创建主界面
它定义了用于创建,销毁,并寻找本地或远程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应用程序时有一些问题,我建议以下
- 创建一个简单的Java库项目(一个简单的罐子没有一个主要方法)
- 添加/服务器/默认/ lib目录(包含jar文件,以便您找回您的EJB的)jar文件到您的Java应用程序,无论您是使用JBoss(我不知道在太阳应用服务器的目录)
- 执行上面的代码
现在,创建另一个项目战争
- 加入我们的项目创建的正上方,并添加<JBOSS_HOME> /客户端(包含jar文件,以便访问我们的EJB的)。 再次,我不知道在太阳应用服务器的目录。 Ckeck出它的文档。
- 见其全球地址的映射中所示答案的上方
而在你的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();
问候,
也许查找字符串实际上应该是: “Java的:comp / env的/ EJB / userManagerBean”?
最后两个答案都正确的,因为它们是你需要改变/修复的东西。 但是你看到的NoSuchMethodError是不是从你的代码,也没有从事物试图找到你的代码(会产生某种NoClassDefFoundException的,我认为,是这一情况)。 这看起来更像是由容器提供的JNDI供应商,并在Java库中的JNDI实现想要什么的不兼容版本。 这是一个相当模糊的回答,但是,会想象它是可能升级的应用程序服务器,并确保你没有部署与应用到JNDI相关的基础设施类,可能会干扰的可能是陈旧的副本可解。
首先,解决您的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,了解更多详情。