jBoss EAR-EJB jndi java:全局工作,java:app NameNotFoundException

时间:2015-09-22 13:36:19

标签: java-ee jboss ejb jndi ear

我们有一个包含一些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 /都是空的

1 个答案:

答案 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名称。