Wildfly 上的 EJB 从另一个 Wildfly 调用远程 EJB

EJB on Wildfly calling remote EJB from another Wildfly

我目前的一般问题是,我的机器上有两个 Wildfly 8.2.0Final 实例 运行。 我知道,有类似的问题,但其中 none 确实有助于解决我的问题。 其中之一拥有一个 restful 应用程序,该应用程序在接收到 GET 时触发无状态会话 bean SenderBean。 之后,这个无状态会话 bean 应该从位于另一个 wildfly 实例上的远程无状态会话 bean PrintBean 调用一个方法。

我将首先解释我到目前为止所做的事情(也许我错过了一些东西,我对 Java EE 和 Wildfly 很陌生)。

我将使用 SenderBean 调用 Wildfly 实例 Sender 并将 PrintBean 调用 Receiver.

我创建了一个名为 Stefan 的应用程序用户,密码为 stefan,属于 Receiver 上的组 guest。 在 Sender 上,在 standalone-full.xml 中,我通过放置

添加了一个安全领域
<security-realm name="ejb-security-realm">
  <server-identities>
    <secret value="c3R1ZmFu"/>
  </server-identities>
</security-realm>

进入 <security-realms> 部分。 我还通过 put

添加了出站套接字绑定
<outbound-socket-binding name="remote-ejb">
  <remote-destination host="localhost" port="8080"/>
</outbound-socket-binding>

进入 <socket-binding-group ...> 部分。 最后,我通过放置

创建了一个出站连接
<outbound-connections>
  <remote-outbound-connection name="remote-ejb-connection" outbound-socket-binding-ref="remote-ejb" username="Stefan" security-realm="ejb-security-realm">
    <properties>
      <property name="SASL_POLICY_NOANONYMOUS" value="false"/>
      <property name="SSL_ENABLED" value="false"/>
    </properties>
  </remote-outbound-connection>
</outbound-connections>

进入<subsystem xmlns="urn:jboss:domain:remoting:2.0">部分。

我使用 CLI 命令 standalone.bat -c standalone-full.xml -Djboss.socket.binding.port-offset=100 -Djboss.node.name=Sender 启动 Sender,使用 standalone.bat -c standalone-full.xml -Djboss.node.name=Receiver 启动 Receiver

Sender 上的本地无状态会话 Bean 称为 SenderBean:

@Stateless
public class SenderBean implements SenderService {

  private static final Logger logger = Logger.getLogger(SenderBean.class.getSimpleName());

  public void send(){
    logger.info("Trying to invoke");
    this.invoke();
  }

  private void invoke() {
    Properties clientProperties = new Properties();
    clientProperties.put("remote.connections", "default");
    clientProperties.put("remote.connection.default.port", "8080");
    clientProperties.put("remote.connection.default.host", "localhost");

    Properties properties = new Properties();
    properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");        

    try {
        Context context = new InitialContext(properties);
        context = new InitialContext(properties);
        Object x = context.lookup("ejb:baseproject-ear-01.00.00-SNAPSHOT/testdomain-service-01.00.00-SNAPSHOT/Receiver/PrintBean!com.schubert.baseproject.testdomain.service.PrintService");
        logger.info("Obtained some object "+x.toString());
        logger.info("Trying to cast.");
        PrintService s = (PrintService) x;
        logger.info("Cast successful");
        logger.info("Printing using remote ejb: "+s.print("Markus"));
    } catch (NamingException e) {
        e.printStackTrace();
    }
  } 
}

并且 Receiver 包含 PrintBean:

@Stateless
@Remote(PrintService.class)
public class PrintBean implements PrintService {

  @Override
  public String print(String name) {
    return "Hello " + name;
  }
}

现在的问题是,我总是得到一个 IllegalStateException,上面写着 EJBCLIENT000025:没有可用于处理的 EJB 接收器...

我是不是做错了什么?我对 EJB 和 Wildfly 还很陌生。 您可以在 GitHub.

上找到项目设置

我认为问题出在InitialContext 的参数上,服务器配置很好。尝试按照我连接到远程队列的示例,如果是普通企业 bean,您也可以探索这种情况(插入正确的用户登录名和密码):

env.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
    env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "client");
    env.put(Context.SECURITY_CREDENTIALS, "q");

    Context ctx = new InitialContext(env);
    connectionFactory = (ConnectionFactory)ctx.lookup("/jms/RemoteConnectionFactory");
    connection = connectionFactory.createConnection("client", "q");

请记住,具有开放外部访问可能性的 jndi 资源必须在服务器配置中以 java:/jboss/exported/ 开头,但在客户端,您可以将此单词下拉。此说明适用于 WildFly,但不适用于 JBoss EAP/AS 等。关注link.

可以获得更多信息

您应该将文件 jboss-ejb-client.xml 添加到您的发件人 EAR(而不是 WAR)。将它放在 application.xml.

旁边

jboss-ejb-client.xml内容:

<jboss-ejb-client>
    <client-context>
        <ejb-receivers>
            <remoting-ejb-receiver outbound-connection-ref="remote-ejb-connection"/>
        </ejb-receivers>
    </client-context>
</jboss-ejb-client> 

在发送者 bean 中,两行就足够了:

Context context = new InitialContext();
Object x = context.lookup("ejb:baseproject-ear-01.00.00-SNAPSHOT/testdomain-service-01.00.00-SNAPSHOT/PrintBean!com.schubert.baseproject.testdomain.service.PrintService");

请注意,我从路径中删除了 "Receiver/"。您可以在服务器日志中找到 JNDI 绑定。

可能你可以找到 detailed description of configuration between a two JBoss servers, source code with configuration files also provided at GitHub quickstart