EJB on Wildfly calling remote EJB from another Wil

2019-06-22 02:51发布

问题:

my current problem in general is, that i have two Wildfly 8.2.0Final instances running on my machine. I know, there are similar questions, but none of them really help with my problem. One of them holds a restful application that triggers a stateless session bean SenderBean when it receives a GET. Afterwards, this stateless session bean should invoke a method from a remote stateless session bean PrintBean, which is located on the other wildfly instance.

I'll start of by explaining what i have done so far (maybe i missed something, i'm quite new to Java EE and Wildfly).

I'm going to call the Wildfly instance with the SenderBean the Sender and the one with the PrintBean the Receiver.

I created an Application user named Stefan with Password stefan, belonging to group guest on the Receiver. On the Sender, in the standalone-full.xml, i added a Security-Realm by putting

<security-realm name="ejb-security-realm">
  <server-identities>
    <secret value="c3R1ZmFu"/>
  </server-identities>
</security-realm>

into the <security-realms> section. I also added a outbound-socket-binding by putting

<outbound-socket-binding name="remote-ejb">
  <remote-destination host="localhost" port="8080"/>
</outbound-socket-binding>

into the <socket-binding-group ...> section. Last, i created an outbound-connection, by putting

<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>

into the <subsystem xmlns="urn:jboss:domain:remoting:2.0"> section.

I start the Sender with the CLI command standalone.bat -c standalone-full.xml -Djboss.socket.binding.port-offset=100 -Djboss.node.name=Sender and the Receiver with standalone.bat -c standalone-full.xml -Djboss.node.name=Receiver.

The Local Stateless Session Bean on the Sender is called 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();
    }
  } 
}

And the Receiver contains the PrintBean:

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

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

the problem now is, I always get a IllegalStateException that says EJBCLIENT000025: No EJB receiver available for handling ...

Am I maybe doing something very wrong? I am fairly new to EJBs and Wildfly. You can find the project setup on GitHub.

回答1:

You should add file jboss-ejb-client.xml to your sender EAR (not to WAR). Place it next to application.xml.

jboss-ejb-client.xml content:

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

In sender bean two lines are enough:

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");

Note that I removed "Receiver/" from path. You can find JNDI bindings in server log.



回答2:

On my mind problem is located in parameters for InitialContext, server configuration are well. Try to follow my example of connection to the remote queue, in case of ordinary enterprise beans you can explore such scenario too (insert correct user login and password):

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");

Remember, that jndi resources with open external access possibility must start at server config with java:/jboss/exported/, but on client side you can drop down this words. This instruction is good for WildFly, but not for JBoss EAP/AS and others. More information you can get by following the link.



回答3:

Posible you can find detailed description of configuration between a two JBoss servers, source code with configuration files also provided at GitHub quickstart