Java 如何使用jndi在wildfly中查找本地bean

Java 如何使用jndi在wildfly中查找本地bean,java,ejb-3.0,jndi,wildfly,Java,Ejb 3.0,Jndi,Wildfly,我的问题似乎和他一样,只是我无法让他的解决方案发挥作用 我对jarjaws-server-ejb3中部署的ejb有一个ear。在我的应用程序中,我想调用bean上的方法。我在我的bean上尝试了使用和不使用@LocalBean的方法 当wildfly(8.2)启动时,它会打印出: java:global/jaws/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote java:app

我的问题似乎和他一样,只是我无法让他的解决方案发挥作用

我对jarjaws-server-ejb3中部署的ejb有一个ear。在我的应用程序中,我想调用bean上的方法。我在我的bean上尝试了使用和不使用
@LocalBean
的方法

当wildfly(8.2)启动时,它会打印出:

java:global/jaws/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:app/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:module/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:jboss/exported/jaws/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:global/jaws/jaws-server-ejb3/ForecastService
java:app/jaws-server-ejb3/ForecastService
java:module/ForecastService
当我将@LocalBean添加到我的bean时,我看到:

java:global/jaws/jaws-server-ejb3/ForecastService!com.termalabs.server.service.ForecastService
java:app/jaws-server-ejb3/ForecastService!com.termalabs.server.service.ForecastService
java:module/ForecastService!com.termalabs.server.service.ForecastService
java:global/jaws/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:app/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:module/ForecastService!com.termalabs.common.service.ForecastServiceRemote
java:jboss/exported/jaws/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote
因此,从我读到的所有内容来看,似乎很清楚,我应该能够使用“java:app/jaws-server-ejb3/ForecastService”或“java:app/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastServiceRemote”来查找这个bean

这是我目前硬编码的查找:

public static Object getBeanInternal(String beanName, Class remoteClass) throws NamingException {
    System.out.println("Getting internal bean: " + beanName + " for class "  + remoteClass.getName());
    final Hashtable jndiProperties = new Hashtable();
    jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    InitialContext ctx = new InitialContext(jndiProperties);
    Object ejb = ctx.lookup("java:app/jaws-server-ejb3/ForecastService");
//    Object ejb = ctx.lookup("java:global/jaws-server-ejb3/ForecastService!com.termalabs.common.service.ForecastService");
    return ejb;
}
我已经用一个空的JNDiproperty表或者上面引用的设置尝试过了。无论我做了什么尝试,我最终都会遇到一个异常,比如

2015-04-07 15:50:01,836 WARN  [com.termalabs.server.system.AutosysJammerSequence] (JammerManager-2015/04/07 15:49:46.710 MDT-0) Can't lookup: javax.naming.NameNotFoundException: java:app/jaws-server-ejb3/ForecastService
    at org.jboss.as.naming.InitialContext$DefaultInitialContext.findContext(InitialContext.java:187)
    at org.jboss.as.naming.InitialContext$DefaultInitialContext.lookup(InitialContext.java:231)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:188)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:184)
    at javax.naming.InitialContext.lookup(InitialContext.java:417) [rt.jar:1.8.0_25]
    at javax.naming.InitialContext.lookup(InitialContext.java:417) [rt.jar:1.8.0_25]
    at com.termalabs.common.ejb3.EJB3Util.getBeanInternal(EJB3Util.java:55) [jaws-common-ejb3intf-1.0.jar:]
    at com.termalabs.server.system.AutosysJammerSequence.runJammerSequence(AutosysJammerSequence.java:427) [jaws-server-base-5.1dev.jar:]
    at com.termalabs.server.system.JammerSequence.run(JammerSequence.java:125) [jaws-server-base-5.1dev.jar:]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [rt.jar:1.8.0_25]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_25]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_25]
我可以使用远程接口访问这个bean,但这似乎不对,因为我是从同一个ear运行此代码的。我不需要那样做

我错过了什么

谢谢


Michael

正在查看我看到的消息,JammerManager-2015/04/07 15:49:46.710 MDT-0,看起来您正在启动自己的线程。如果您没有使用新的EE并发实用程序,则可能没有将命名上下文复制到线程中。您需要确保为新线程设置了命名上下文、安全上下文和TCCL。

是您要查找和使用部署在同一可部署单元(如在同一战争中)中的EJB的代码吗?如果是这样的话,为什么要使用JNDI来执行查找,而您可以使用“@inject”或“@EJB”来代替它呢?我只是想指出,在您注释掉的查找中,您指定了“java:global”而不是“java:app”。不知道这是否有用。@KevinHooke-原则上我应该使用“@EJB”,但出于历史原因,我们在CDI中使用Guice,我希望不必教Guice有关“@EJB”的知识。这是有道理的。我一度假回来就调查此事。谢谢你说得对。我可以从父线程访问bean,但不能从新线程内部访问。我似乎有两个选择:1)使用JBoss/JavaEE API重写所有线程。这显然是更可取的,除了我们绕过标准CDI和使用GUI而变得困难之外。这将是一种相当侵入性的行为。2) 照你说的做,在我的命名上下文、安全上下文和TCCL中复制。你有什么可以说明如何做到这一点的指针吗?我在谷歌的运气不太好。再次感谢。看看a是如何推出的。看一看,谢谢你的帮助,詹姆斯。它为我指明了使用正确创建的Bean来创建所需线程的正确方向。一旦我的线程被Wildfly实际管理,我就能够正确地在bean上调用我的方法。遵循EJB规范:不要自己启动任何线程,因为它会“混淆”容器,甚至可能崩溃。这就是我学到的。