我们有一个包含一些jar,一个EJB模块和一个WAR模块的EAR。我们希望从相同的EJB模块获取具有JNDI InitialContext.lookup的类。
在jBoss控制台中,我们可以看到java:global与应用程序,模块以及模块内的所有类。如果我们进行查找就像它可以工作一样。 还有一个应用程序部分,其中包含我们的EAR以及模块和内部的所有类。
现在我们的EAR可以有不同的执行,因此不同的二进制名称,我们想使用java:app跳过硬编码的AppName。令我们惊讶的是,即使java:app存在于jBoss控制台JNDI列表中,它也会一直抛出一个NameNotFoundException。我们还尝试使用java:comp,java:module,java:app / env / ...(即使它们没有显示在jBoss控制台中),但除了可移植名称之外什么都没有。
有谁知道为什么会发生这种情况?
private static final String MY_TIMER_SINGLETON = "java:global/myear-1.0.0-SNAPSHOT/mymoduleejb/MyTimerSingleton";
//private static final String MY_TIMER_SINGLETON = "java:app/mymoduleejb/MyTimerSingleton";
InitialContext ic = new InitialContext();
MyTimerSingleton t = (MyTimerSingleton) ic
.lookup(MY_TIMER_SINGLETON);
JBoss控制台Profile-> Container->命名:
java:jboss
-...
java:global
-myear-1.0.0-SNAPSHOT
-mymoduleejb
-MyTimerSingleton
-...
applications
-myear-1.0.0-SNAPSHOT
-java:app
-mymoduleear
-MyTimerSingleton
-...
编辑1:补充信息。
jBoss正在使用standalone-ha.xml配置运行。
我试图通过JDNI获取Singleton,因为@EJB在org.jboss.msc.service.Service类中不起作用。
如果我让MyTimerSingleton实现了@Remote或@Local接口,那么JBoss控制台的JNDI就会变空。
在任何情况下,JNDI列表的所有... / env /都是空的
答案 0 :(得分:1)
我假设 MyTimerSingleton 是一个EJB,如果它不是你不需要JNDI,你可以使用 @EJB 注释,甚至用于从内部的Web模块调用EJB。
...
@Stateless
public class OtherEJB {
@EJB
MyTimerSingleton myTimerSingleton;
...
如果您想要使用JNDI调用来实现松散耦合的解决方案,请尝试使用 @Stateless 或 @Singleton <中的 mappedName 属性/ strong>注释 EJB MyTimerSingleton :
...
import javax.ejb.Singleton;
@Singleton(mappedName = "MyTimerSingleton")
public class MyTimerSingleton implements MyTimerSingletonDef {
...
您还需要编写/生成 EJB @Local或@Remote接口。
...
@Remote
public interface MyTimerSingletonDef {
...
mappedNames 支持的Java-EE提供程序实现可能不同,通常EJB模块的JNDI NAME是这样的: java:module / ejb-mappedName-property!canonical- ejb-interface-name 或 java:module / ejb-mappedName-property#canonical-ejb-interface-name ,所以你会得到这样的东西:
java:module/MyTimerSingleton!example.package.MyTimerSingletonDef
或者
java:module/MyTimerSingleton#example.package.MyTimerSingletonDef
根据this blog,以及JBoss和WildFly案例中的JBoss documentation
从Java EE 6开始,EJB的JNDI名称语法 组件具有以下结构:
[/<application-name>]/<module-name>/<bean-name>[!<full-qualified-interface-name>]
默认情况下,应用程序名称是企业的文件名 存档。因此,建议配置应用程序 在企业的application.xml部署描述符中的名称 存档,如下所示。
<application xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/application_7.xsd"
version="7">
<application-name>myapp</application-name>
...
</application>
还建议配置ejb模块的模块名称。 否则,模块名称默认为ejb的文件名 存档。可以使用ejb-jar.xml配置模块名称 部署描述符。
<ejb-jar xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/ejb-jar_3_2.xsd"
version="3.2">
<module-name>remote</module-name>
</ejb-jar>
根据规范,EJB组件将在其中注册 名称空间java:global,java:app和java:module。
所以你在服务器控制台中得到这样的东西:
java:global/myapp/remote/MyTimerSingleton!example.package.MyTimerSingletonDef
java:app/myapp/remote/MyTimerSingleton!example.package.MyTimerSingletonDef
java:module/myapp/MyTimerSingleton!example.package.MyTimerSingletonDef
因此,解决方案可能是配置应用程序(在application.xml中)和ejb-module(ejb-jar.xml)名称以始终获得相同的可移植JNDI名称。