【问题标题】:Can't get Remote EJB to work with EJB Client API on Wildfly无法让远程 EJB 与 Wildfly 上的 EJB 客户端 API 一起工作
【发布时间】:2015-10-02 09:50:38
【问题描述】:

我目前正在努力让远程 EJB 调用在 Wildfly(8.x 和 9.x)上工作。

详细地说,它是关于使用 EJB 客户端 API 方法从独立客户端应用程序(而不是来自另一个应用程序服务器)进行远程调用。远程命名方法适用于我,但不适用于我的场景,因为我需要使用客户端拦截器将上下文数据传递给远程调用的服务器端拦截器。

但现在我尝试使用客户端 API 进行远程调用,以作为一个简单的示例。因此,我尝试了远程 ejb 调用的快速入门,该快速入门可在 github (wildfly/quickstart/ejb-remote) 上找到。关键是这个快速入门会引发与我在简单示例应用程序中相同的错误。以下是我的申请的一些细节:

我的远程界面:

package test.ejb;

public interface HelloRemote {
  String greet(String name);
}

我的 Bean 实现:

package test.ejb;
import javax.ejb.Remote;
import javax.ejb.Stateless;

@Stateless(name = "Hello")
@Remote(HelloRemote.class)
public class HelloBean implements HelloRemote {

  public String greet(String name) {
    return "Hello " + name;
  }
}

bean 的远程视图已在服务器上正确注册(在导出命名空间中):

java:jboss/exported/ejb-test-backend.jar/Hello!de.coryx.HelloRemote

现在是客户端:

我的主班:

import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.jboss.ejb.client.EJBClientContext;
import test.ejb.HelloRemote;

public class Main {
  public static void main(String[] args) throws Exception {
    Properties props = new Properties();
    props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    Context context = new InitialContext(props);

    String jndiLookup = "ejb:/ejb-test-backend.jar/Hello!" + HelloRemote.class.getName();
    HelloRemote hello = (HelloRemote) context.lookup(jndiLookup);
    System.out.println(hello.greet("World"));
  }
}

jboss-ejb-client.properties(打包在jar/META_INF中):

endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false

remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false

当我执行 main 方法时,我收到以下错误消息(尝试上面提到的 wildfly 快速入门时也会出现同样的情况):

Exception in thread "main" java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:, moduleName:ejb-test-backend.jar, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@497470ed
    at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:774)
    at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116)
    at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:186)
    at org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:255)
    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:200)
    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:183)
    at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146)
    at com.sun.proxy.$Proxy0.greet(Unknown Source)
    at Main.main(Main.java:16)

当我使用远程命名方法时,一切都很好:

Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
props.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080");
props.put("jboss.naming.client.ejb.context", true);
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
props.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
Context context = new InitialContext(props);

String jndiLookup = "/ejb-test-backend.jar/Hello!" + HelloRemote.class.getName();
HelloRemote hello = (HelloRemote) context.lookup(jndiLookup);
System.out.println(hello.greet("World"));

这里的输出是(如预期的那样):

Hello World

那么有没有人知道这里可能出了什么问题或者更好,谁有一个使用 EJB 客户端 API 在 Wildfly 上进行远程 EJB 调用的工作示例? 提前致谢!

【问题讨论】:

  • 好的,我的调查更深入了。似乎没有加载客户端属性文件,因此 EJB 定位器没有连接详细信息。我通过使用 -Djboss.ejb.client.properties.file.path VM-Argument 将属性文件显式传递给进程发现了这一点。在这种情况下调用成功!但是为什么这个属性文件没有从 META-INF 加载呢?为什么快速入门……不起作用?有什么变化吗?

标签: java jakarta-ee ejb wildfly wildfly-8


【解决方案1】:

像往常一样,我在写下问题并谈论它后不久就偶然发现了解决方案。

这个设置的问题是 jboss-ejb-client.properties 文件没有被客户端 API 加载,然后缺少连接 url,...

我不知道是否对必须放置这些属性的所需位置进行了更改,或者我是否太笨而无法正确阅读,或者我是否只是改编了一个损坏的教程。没关系;)

解决办法是把属性文件toplevel放在classpath下,而不是JAR的META-INF目录下!

它现在按预期工作,我可以注册客户端拦截器。

【讨论】:

    猜你喜欢
    • 2015-04-26
    • 2014-01-16
    • 2015-04-20
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 2015-05-21
    • 2016-06-01
    相关资源
    最近更新 更多