WildFly: EJB invocations from a remote client

Tapas Bose picture Tapas Bose · Dec 28, 2013 · Viewed 14.9k times · Source

I was trying to lookup and call an EJB deployed as EAR in WildFly. I have tried different ways.

Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");        
properties.put(Context.PROVIDER_URL, "remote://localhost:4447");
properties.put(Context.SECURITY_PRINCIPAL, myUser);
properties.put(Context.SECURITY_CREDENTIALS, myPassword);    
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");

InitialContext context = new InitialContext(properties);
Object object = context.lookup(jndi);
MyService service = (MyService)object;
System.out.println(service.echo("JYM"));

It has thrown:

javax.naming.NamingException: Failed to connect to any server. Servers tried: [remote://localhost:4447]
    at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:213)
    at org.jboss.naming.remote.client.HaRemoteNamingStore.namingStore(HaRemoteNamingStore.java:144)
    at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:125)
    at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:241)
    at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:79)
    at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:83)
    at javax.naming.InitialContext.lookup(InitialContext.java:417)
    at com.app.test.service.MyServiceTest.echo(MyServiceTest.java:60)

If I add the following properties:

properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
properties.put("jboss.ejb.client.scoped.context", "true");

I recieved:

java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:roolafic, moduleName:usermanagement, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@3c0f93f1
    at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:749)
    at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:116)
    at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:183)
    at org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:253)
    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:198)
    at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:181)
    at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:144)
    at com.sun.proxy.$Proxy4.echo(Unknown Source)
    at com.app.test.service.MyServiceTest.echo(MyServiceTest.java:62)

Then I saw a Jboss forum post which says to use http-remoting instead of remote. But that also didn't work. Even using port 8080.

I have tried the way mentioned here. But it seems that it would not work for my case. Though I have placed the jboss-ejb-client.properties in the same directory from where I am running my client method from Eclipse.

Answer

Tapas Bose picture Tapas Bose · Dec 28, 2013

After spending almost half a day I found the solution. Here it is:

public static <T> T connectEJB(String jndi) throws NamingException {
    Properties clientProperties = new Properties();
    clientProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
    clientProperties.put("remote.connections", "default");
    clientProperties.put("remote.connection.default.port", myPort);
    clientProperties.put("remote.connection.default.host", myHost);
    clientProperties.put("remote.connection.default.username", myUser);
    clientProperties.put("remote.connection.default.password", myPassword);
    clientProperties.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");

    EJBClientConfiguration ejbClientConfiguration = new PropertiesBasedEJBClientConfiguration(clientProperties);
    ContextSelector<EJBClientContext> contextSelector = new ConfigBasedEJBClientContextSelector(ejbClientConfiguration);
    EJBClientContext.setSelector(contextSelector);

    Properties properties = new Properties();
    properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    Context context = new InitialContext(properties);
    return (T) context.lookup(jndi);
}

For more information see here. Hope it will be helpful to others.