【问题标题】:JNDI No EJB receiver available for handlingJNDI 没有可用于处理的 EJB 接收器
【发布时间】:2016-07-17 12:57:23
【问题描述】:

我的 EJBTest 有问题。

我已经安装了 WildFly 并配置了用户管理和应用程序管理。

我写了一个 EJB 3.0 并部署了它:

@Stateless
@Remote(NewSessionBeanRemote.class)
public class NewSessionBean implements NewSessionBeanRemote {

    List<String> bookShielf;

    /**
     * Default constructor. 
     */
    public NewSessionBean() {
        bookShielf = new ArrayList<String>();
    }

    @Override
    public void addBook(String bookName) {
        bookShielf.add(bookName);
    }

    @Override
    public List getBook() {
        return bookShielf;
    }
}

后来我写了一个简单的客户端来连接它:

private static void invokeStatelessBean() throws NamingException {
    // Let's lookup the remote stateless calculator
    NewSessionBeanRemote remoteEjb = lookupRemoteSessionBean();
    System.out.println("Obtained a remote stateless calculator for invocation");
    String bookName = "TEST book";
    remoteEjb.addBook(bookName);
}

private static NewSessionBeanRemote lookupRemoteSessionBean() throws NamingException {

    final Hashtable jndiProperties = new Hashtable();
    jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
    jndiProperties.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:10090");
    jndiProperties.put(Context.SECURITY_PRINCIPAL, "ejb"); //this is the application user name, not management! it's correct?
    jndiProperties.put(Context.SECURITY_CREDENTIALS, "ejb");//this is the application password, not management! it's correct?
    jndiProperties.put("jboss.naming.client.ejb.context", true);
    final Context context = new InitialContext(jndiProperties);
    final String appName = "";
    final String moduleName = "EjbComponent";
    final String distinctName = "";
    final String beanName = NewSessionBean.class.getSimpleName();
    final String viewClassName = NewSessionBeanRemote.class.getName();
    System.out.println("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
    return (NewSessionBeanRemote) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
}

用户名和密码都是应用程序用户凭证,不是管理!对吗?

我收到此错误:

线程“main”中的异常 java.lang.IllegalStateException: EJBCLIENT000025: 没有 EJB 接收器可用于处理调用上下文 org.jboss.ejb.client.EJBClientInvocationContext@5034c75a 的 [appName:, moduleName:EjbComponent, distinctName:] 组合 在 org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:798) 在 org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:128) 在 org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:186) 在 org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:255) 在 org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:200) 在 org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:183) 在 org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146) 在 com.sun.proxy.$Proxy2.addBook(未知来源) 在 com.studio.java.client.EjbTester.invokeStatelessBean(EjbTester.java:34) 在 com.studio.java.client.EjbTester.main(EjbTester.java:21)

我不知道为什么!有人有想法吗?

【问题讨论】:

    标签: java error-handling ejb jndi wildfly-10


    【解决方案1】:

    您收到上述错误是因为您尝试使用绝对 JNDI 名称访问远程 EJB。

    documentation所述:

    http-remoting 客户端假定远程查找中的 JNDI 名称是相对于 java:jboss/exported 命名空间的,因此查找绝对 JNDI 名称将失败。 p>

    因此,在 WildFly 上部署应用程序后,您应该会在服务器控制台上看到如下内容:

    JNDI bindings for session bean named NewSessionBean in deployment unit deployment <your_deployment_unit> are as follows:
    
        java:global[/<application_name>]/<module_name>/<ejb_name>[!<interface_name>]
        java:app[/<module_name>]/<ejb_name>[!<interface_name>]
        java:module/<ejb_name>[!<interface_name>]
        java:jboss/exported[/<application_name>]/<module_name>/<ejb_name>[!<interface_name>]
        java:global/[/<application_name>]/<module_name>/<ejb_name>
        java:app[/<module_name>]/<ejb_name>
        java:module/<ejb_name>
    

    因此,考虑到 java:jboss/exported 上下文,获得 EJB 的正确方法应该是:

    // Normally the appName is the EAR name
    // Leave it empty if your application isn't packaged in a EAR
    String appName = "your_application_name/";
    // The EJB module name
    String moduleName = "ejb_module_name/";
    String beanName = NewSessionBean.class.getSimpleName();
    String viewClassName = NewSessionBeanRemote.class.getName();
    
    (NewSessionBeanRemote) context.lookup(appName + moduleName + beanName + "!" + viewClassName);
    

    为了进一步阅读,我建议你也看看Java EE JNDI Syntax以及WildFly's JNDI Reference

    关于您的凭据,它们不是必需的,因为您的 EJB 不需要任何类型的身份验证即可访问它。通常,仅当您拥有使用 LDAP service provider 的应用程序时才需要这样做。

    【讨论】:

    • 好的!非常感谢 Aribeiro,但现在我收到 java.lang.ClassCastException: org.jboss.ejb.client.naming.ejb.EjbNamingContext cannot be cast to com.studio.java.NewSessionBeanRemote
    • 您的查找情况如何?
    • 总是演员例外 :(
    • 我在询问您在context.lookup 中使用的字符串。这是什么?
    • 我认为查找没问题,但现在我有另一个错误..当我尝试查找此行时: (NewSessionBeanRemote) context.lookup("ejb:" + appName + "" + moduleName + "" + distinctName + "" + beanName + "!" + viewClassName);
    猜你喜欢
    • 2013-02-28
    • 1970-01-01
    • 2017-04-19
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    相关资源
    最近更新 更多