我目前正在努力使远程EJB调用能够在wildfly(8.x和9.x)上运行。
详细介绍了使用EJB Client API方法从独立客户端应用程序(而非其他应用程序服务器)远程调用的问题。远程命名方法对我有用,但在我的场景中不适用,因为我需要使用客户端拦截器将上下文数据传递给远程调用的服务器端拦截器。
但是现在我尝试使用客户端API进行远程调用以用于一个简单的示例。因此,我尝试了在github(wildfly/quickstart/ejb-remote)上提供的远程ejb调用的快速入门。关键是这个快速入门引发了与我在简单示例应用程序上相同的错误。以下是我的申请的一些细节:
我的远程界面:
package test.ejb;
public interface HelloRemote {
String greet(String name);
}
My 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调用的工作示例? 提前谢谢!
答案 0 :(得分:1)
经常,在写完问题并谈论它之后,我偶然发现了解决方案。
这个设置的问题是客户端API没有加载jboss-ejb-client.properties文件,然后错过了连接URL,...
我不知道是否存在必须放置这些属性的所需位置的更改,或者我是否太愚蠢无法正确阅读或者我是否只修改了已损坏的教程。它甚至不重要;)
解决方案是将属性文件放在类路径上,而不是放在JAR的META-INF目录中!
现在按预期工作,我可以注册客户端拦截器。