3

I'm currently struggling with getting remote EJB invocation to work on wildfly (8.x and 9.x).

In detail it's about remote invocation from a standalone client application (not from another app server) using the EJB Client API approach. The remote naming approach works for me but isn't applicable in my scenario because I need to use client-side interceptors for passing context data to a server-side interceptor for the remote invocations.

But for now I try to get remote invocations with the client API to work for a simple example. Therefore I tried the quickstart for remote ejb invocation which is available on github (wildfly/quickstart/ejb-remote). The point is that this quickstart raises the same error as my on simple sample app. Here are some details of my application:

My remote interface:

package test.ejb;

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

My Bean implementation:

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

The remote view of the bean is correctly registered at the server (in export namespace):

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

Here now the client side:

My Main class:

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

The jboss-ejb-client.properties (packaged in 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

When I execute the main Method I get the following error message (same thing occurs when trying the wildfly quickstart that I mentioned above):

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)

When I use the remote naming approach everything is fine:

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

Output here is (as expected):

Hello World

So is there anyone who knows what could be wrong here or better, who has a working example for remote EJB invocation on Wildfly using the EJB client API? Thanks in advance!

shillner
  • 1,806
  • 15
  • 24
  • Ok, I'm a bit further in my investigation. It seems that the client properties file wasn't loaded and thus the EJB locator had no connection details. I found this out by passing the properties file explicitly to the process using the -Djboss.ejb.client.properties.file.path VM-Argument. In this case the invocation succeeds! But why is this properties file not loaded from META-INF? And why are the quickstarts, ... not working? Have there been any changes? – shillner Oct 02 '15 at 11:39

1 Answers1

2

As so often, I stumbled over the solution shortly after writing down the question and talking about it.

The problem with this setup was that the jboss-ejb-client.properties file has not been loaded by the client API which was then missing the connection url, ...

I don't know whether there where changes to the required location where these properties have to be placed or whether I was too dumb to read it correctly or whether I just adapted a tutorial that was corrupted. It doesn't even matter ;)

The solution is to place the properties file toplevel on the classpath and not in the META-INF directory of the JAR!

It works now as expected and I can register client-side interceptors.

shillner
  • 1,806
  • 15
  • 24