【问题标题】:Java: JNDI Lookup fails when ran inside a ThreadJava:在线程内运行时 JNDI 查找失败
【发布时间】:2020-03-16 16:43:25
【问题描述】:

我在使用 Wildfly 18 进行 JNDI 查找时遇到了一种相当奇怪的行为。我有一个简单的 EJB:

package com.getronics.ejb;

import javax.ejb.Remote;
import javax.ejb.Local;
import javax.ejb.Stateless;

@Stateless
@Local(ICalculadoraLocal.class)
public class CalculadoraBean implements ICalculadoraLocal {
        public int suma(int a, int b){
               return a+b;
        }
}

界面简洁:

package com.getronics.ejb;

public interface ICalculadoraLocal{
        int suma(int a, int b);
}

还有一个简单的 JSP 页面来检查它:

<html>
    <body>
            <%@ page import="java.util.Hashtable,javax.naming.*,com.getronics.ejb.*" %>
            request: <%= request.getRequestURI()%><br>
            <%
              final Hashtable jndiProperties = new Hashtable();
              jndiProperties.put(Context.URL_PKG_PREFIXES,"org.jboss.ejb.client.naming");
              final Context context = new InitialContext(jndiProperties);
              ICalculadoraLocal calculadora = (ICalculadoraLocal)context.lookup("java:app/ejb-0.0.0.0.0.1/CalculadoraBean!com.getronics.ejb.ICalculadoraLocal");
              int suma = calculadora.suma(2,2);
                    %>
                    context: <%= context%></br>
                    2+2= <%=suma%>
    </body>
</html>

这很好用:

request: /ejb/index.jsp
context: javax.naming.InitialContext@3e532295
2+2= 4

但是,当我尝试使用线程时,如下所示:

<html>
    <body>
            <%@ page import="java.util.Hashtable,javax.naming.*,com.getronics.ejb.*" %>
            request: <%= request.getRequestURI()%><br>
            <%
                new Thread() {
                    public void run() {
                            try {
                              final Hashtable jndiProperties = new Hashtable();
                              jndiProperties.put(Context.URL_PKG_PREFIXES,"org.jboss.ejb.client.naming");
                              final Context context = new InitialContext(jndiProperties);
                              ICalculadoraLocal calculadora = (ICalculadoraLocal)context.lookup("java:app/ejb-0.0.0.0.0.1/CalculadoraBean!com.getronics.ejb.ICalculadoraLocal");
                              int suma = calculadora.suma(2,2);
                              System.out.println("suma: " + suma);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        };
                    }.start();
                    %>
    </body>
</html>

它抛出一个 NameNotFoundException:

javax.naming.NameNotFoundException: java:app/ejb-0.0.0.0.0.1/CalculadoraBean!com.getronics.ejb.ICalculadoraLocal

关于为什么会发生这种情况的任何想法?

【问题讨论】:

  • 问题原因在其他地方,而不是在您向我们展示的片段中。我在 Wildfly 18 中通过 JNDI 查找类,在线程内部和外部都没有问题。我建议列出整个 JNDI 上下文的内容,然后你会看到里面的内容。
  • 错误,没有。 所有 JNDI 查找都在线程内运行。
  • 你应该看看我的例子,看看“不可能的原因”有多大可能。
  • 你的回答证明了我的观点。它与线程无关,与app 对 global 完全有关。我很困惑为什么你首先要在单独的线程中运行这段代码。

标签: java thread-safety wildfly jndi


【解决方案1】:

似乎使用“global”而不是“app”使其工作:

ICalculadoraLocal calculadora = (ICalculadoraLocal)context.lookup("java:global/ear-0.0.0.0.0.1/ejb-0.0.0.0.0.1/CalculadoraBean!com.getronics.ejb.ICalculadoraLocal");

原因似乎是“app”、“module”和“comp”的 JNDI 查找在规范中无法在这些线程中工作。

您可以查看这些链接了解更多信息:

jndi lookup fails in user-thread

[jboss-as7-dev] Issue with access to java:comp/UserTransaction from non EE threads

【讨论】:

  • 切线地,找到的唯一官方外观的文档是:“可移植 JNDI 语法”here - 注释了 global、module 和 app 之间的差异。但这都是在 10 多年前的 EJB 的背景下。
猜你喜欢
  • 2019-03-19
  • 2013-06-29
  • 2018-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多