Remote EJB calls from another WildFly Instance
stevehayesxx Jan 24, 2017 8:05 AMHi,
I'm currently involved in porting our application from JBoss 4.3.0 to WildFly 10.1.0.Final.
Part of that port involves accessing EJBs remotely from both a standalone client and from another WildFly instance.
I have the standalone client working, but I cannot get remote EJB calls to work from WildFly. I've tried every
combination I can find in forums / documentation etc, hence the post here now. For reasons that I won't go into here,
I would like to use the programmatic client approach as opposed to setting up the connections in standalone-full.xml.
For the working client I have the following:
1. JBoss client jar from WildFly bin/client dir on the class path
2. The following jboss-ejb-client.properties file on the class path:
remote.connections=conn1
remote.connection.conn1.host=hostname
remote.connection.conn1.port=8080
remote.connection.conn1.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.conn1.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false
remote.connection.conn1.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=${host.auth:JBOSS-LOCAL-USER}
remote.connection.conn1.username=PARSservice
remote.connection.conn1.password=ff705b9eef086335df8592078de921bc
3. The following code to create the InitialContext and do the lookup (lookup names are in the form 'ejb:APP/Module/Bean!Interface'):
public static <T> T getFromRemoteContext( final String hostName, final String name ) throws NamingException {
InitialContext ctx = getServerContext( hostName );
return (T) ctx.lookup( name );
}
private static InitialContext getServerContext( final String hostName ) throws NamingException {
return new InitialContext( getEnv(hostName) );
}
private static Properties getEnv( final String server ) {
Properties env = new Properties();
env.put( Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory" );
env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
env.put("jboss.naming.client.ejb.context", true);
env.put( "jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false" );
env.put( "jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false" );
String port = System.getProperty("interica.ejbremoting.port");
if ( port == null ) {
log.warn( "No port specified for remoting. Defaulting to 8080." );
port = "8080";
}
env.put(Context.PROVIDER_URL, "http-remoting://" + server + ":"+port);
try {
ServiceUser serviceUser = ServiceUserFactory.getServiceUser();
env.put( Context.SECURITY_PRINCIPAL, serviceUser.getUsername() );
env.put( Context.SECURITY_CREDENTIALS, serviceUser.getPasswordAsString() );
} catch ( IOException e ) {
log.error( e.getMessage(), e );
}
return env;
}
4. The following in standalone-full.xml:
<security-realm name="IntericaRealm">
<authentication>
<jaas name="Interica"/>
</authentication>
</security-realm>
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="IntericaRealm"/>
For calls from another WildFly instance I have tried the above with both the JBoss client jar from WildFly bin/client dir on the class path of my APP ear and
also with the following dependencies in the jboss-deployment-structure.xml in the APP ear acting as the client:
<module name="org.jboss.remote-naming" export="true"/>
<module name="org.jboss.xnio" export="true"/>
With each of these I get the following error:
2017-01-24 12:18:56,186 ERROR [ServerRegistrationThread] EJBCLIENT000025: No EJB receiver available for handling [appName:PARSAPP, moduleName:ejb-jar, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@1b12a1a4
java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:PARSAPP, moduleName:ejb-jar, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext@1b12a1a4
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:798)
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:128)
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.$Proxy89.registerNode(Unknown Source)
at com.enigmadata.core.registration.node.service.ServerRegistrationThread.run(ServerRegistrationThread.java:68)
at org.jboss.as.ee.concurrent.ControlPointUtils$ControlledRunnable.run(ControlPointUtils.java:105)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.glassfish.enterprise.concurrent.internal.ManagedFutureTask.run(ManagedFutureTask.java:141)
at org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor$ManagedScheduledFutureTask.access$101(ManagedScheduledThreadPoolExecutor.java:383)
at org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor$ManagedScheduledFutureTask.run(ManagedScheduledThreadPoolExecutor.java:532)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.glassfish.enterprise.concurrent.ManagedThreadFactoryImpl$ManagedThread.run(ManagedThreadFactoryImpl.java:250)
After seeing some other posts, I've now removed the jboss-ejb-client.properties file from the class path and am using the following code for
creating the InitialContext and doing the lookups from WildFly:
public static <T> T getFromRemoteContext( final String hostName, final String name ) throws NamingException {
InitialContext ctx = getServerContext( hostName );
return (T) ctx.lookup( name );
}
private static InitialContext getServerContext( final String hostName ) throws NamingException {
return new InitialContext( getEnv(hostName) );
}
private static Properties getEnv( final String server ) {
String port = System.getProperty("interica.ejbremoting.port");
if ( port == null ) {
log.warn( "No port specified for remoting. Defaulting to 8080." );
port = "8080";
}
String username = "unknown";
String password = "unknown";
try {
ServiceUser serviceUser = ServiceUserFactory.getServiceUser();
username = serviceUser.getUsername();
password = serviceUser.getPasswordAsString();
} catch ( IOException e ) {
log.error( e.getMessage(), e );
}
Properties env = getWildFlyClientConnectionProperties( username, password, server, port );
env.put( Context.PROVIDER_URL, "http-remoting://" + server + ":" + port );
env.put( Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory" );
env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
env.put("jboss.naming.client.ejb.context", false);
env.put("org.jboss.ejb.client.scoped.context", true);
env.put( "jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false" );
env.put( "jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false" );
env.put( Context.SECURITY_PRINCIPAL, username );
env.put( Context.SECURITY_CREDENTIALS, password );
return env;
}
private static Properties getWildFlyClientConnectionProperties( final String username,
final String password,
final String host,
final String port ) {
Properties p = new Properties();
p.put( "endpoint.name", "client-endpoint");
p.put( "remote.connections", "conn1");
p.put( "remote.connection.conn1.username", username );
p.put( "remote.connection.conn1.password", password );
p.put( "remote.connection.conn1.host", host );
p.put( "remote.connection.conn1.port", port );
p.put( "remote.connection.conn1.create.options.org.xnio.Options.SSL_ENABLED", false);
p.put( "remote.connection.conn1.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", false );
p.put( "remote.connection.conn1.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", false );
p.put( "remote.connection.conn1.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER" );
p.put( "remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", false );
return p;
}
The above code gives me the following error (not sure whether this is a step forwards or backwards):
17:55:12,877 WARN [org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector] (EE-ManagedScheduledExecutorService-default-Thread-1) Could not register a EJB receiver for connection to anl0343:8080: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
at org.jboss.remoting3.remote.ClientConnectionOpenListener.allMechanismsFailed(ClientConnectionOpenListener.java:114)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:449)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:241)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:198)
at org.xnio.channels.TranslatingSuspendableChannel$1.handleEvent(TranslatingSuspendableChannel.java:112)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.ChannelListeners$DelegatingChannelListener.handleEvent(ChannelListeners.java:1092)
at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:89)
at org.xnio.nio.WorkerThread.run(WorkerThread.java:567)
at ...asynchronous invocation...(Unknown Source)
at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:294)
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:430)
at org.jboss.ejb.client.remoting.EndpointPool$PooledEndpoint.connect(EndpointPool.java:192)
at org.jboss.ejb.client.remoting.NetworkUtil.connect(NetworkUtil.java:153)
at org.jboss.ejb.client.remoting.NetworkUtil.connect(NetworkUtil.java:133)
at org.jboss.ejb.client.remoting.ConnectionPool.getConnection(ConnectionPool.java:78)
at org.jboss.ejb.client.remoting.RemotingConnectionManager.getConnection(RemotingConnectionManager.java:51)
at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.setupEJBReceivers(ConfigBasedEJBClientContextSelector.java:161)
at org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector.getCurrent(ConfigBasedEJBClientContextSelector.java:118)
at org.jboss.ejb.client.naming.ejb.EjbNamingContext.createIdentifiableEjbClientContext(EjbNamingContext.java:269)
at org.jboss.ejb.client.naming.ejb.EjbNamingContext.setupScopedEjbClientContextIfNeeded(EjbNamingContext.java:134)
at org.jboss.ejb.client.naming.ejb.EjbNamingContext.<init>(EjbNamingContext.java:101)
at org.jboss.ejb.client.naming.ejb.ejbURLContextFactory.getObjectInstance(ejbURLContextFactory.java:38)
at org.jboss.as.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:133)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.enigmadata.core.common.locator.ServiceLocator.getFromRemoteContext(ServiceLocator.java:39)
at com.enigmadata.core.registration.node.service.ServerRegistrationThread.getRegistrationFacade(ServerRegistrationThread.java:101)
at com.enigmadata.core.registration.node.service.ServerRegistrationThread.run(ServerRegistrationThread.java:54)
at org.jboss.as.ee.concurrent.ControlPointUtils$ControlledRunnable.run(ControlPointUtils.java:105)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.glassfish.enterprise.concurrent.internal.ManagedFutureTask.run(ManagedFutureTask.java:141)
at org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor$ManagedScheduledFutureTask.access$101(ManagedScheduledThreadPoolExecutor.java:383)
at org.glassfish.enterprise.concurrent.internal.ManagedScheduledThreadPoolExecutor$ManagedScheduledFutureTask.run(ManagedScheduledThreadPoolExecutor.java:532)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.glassfish.enterprise.concurrent.ManagedThreadFactoryImpl$ManagedThread.run(ManagedThreadFactoryImpl.java:250)
Any help would be gratefully received!