remote ejb fails despite successful handshake
thebravedave Apr 11, 2012 5:38 PMHello, I have tried all sorts of experimentation to get a remote ejb call working, but to no avail.
I have a remote ejb within an ear deployed on our company server.
I have a client ejb within an ear deployed on my local server.
This is a permutation of the quickstarts project https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI
The only change is I put the remote ejb in an ear, and changed the executable jar to an ejb within an ear.
I am obtaining my jboss-ejb-client.properties file by specifying its location within standalone.conf.bat as such:
set "JAVA_OPTS=%JAVA_opts% -Djboss.ejb.client.properties.file.path=C:\JBoss\jboss-as-7.1.1.Final\bin\jboss-ejb-client.properties"
Here is the error I am getting when I start up my local jboss 7.1.1.final server that has my client ejb within an ear in the deployments folder.
13:58:33,428 INFO [org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver] (ServerService Thread Pool -- 30) Succe
ssful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientCo
ntext@20a50d39, receiver=Remoting connection EJB receiver [connection=Remoting connection <70652eb3>,channel=jboss.ejb,n
odename=asdeveug02]} on channel Channel ID 89e8fa46 (outbound) of Remoting connection 3adc4833 to asdeveug02.realserver.net/10.30.17.767:4447
13:58:33,481 WARN [org.jboss.ejb.client.remoting.ChannelAssociation] (Remoting "config-based-ejb-client-endpoint" task-
1) Unsupported message received with header 0xffffffff
...
...
13:58:34,690 INFO [org.jboss.ejb.client] (MSC service thread 1-14) JBoss EJB Client version 1.0.5.Final
13:58:34,696 INFO [stdout] (MSC service thread 1-14) Obtained a remote stateless calculator for invocation
13:58:34,699 INFO [stdout] (MSC service thread 1-14) Adding 204 and 340 via the remote stateless calculator deployed on
the server
13:58:34,710 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-14) MSC00001: Failed to start service jboss.deploy
ment.subunit."jboss-as-ejb-remote-client-ear-7.1.1-SNAPSHOT.ear"."jboss-as-ejb-remote-client-7.1.1-SNAPSHOT.jar".compone
nt.RemoteEJBClient.START: org.jboss.msc.service.StartException in service jboss.deployment.subunit."jboss-as-ejb-remote-
client-ear-7.1.1-SNAPSHOT.ear"."jboss-as-ejb-remote-client-7.1.1-SNAPSHOT.jar".component.RemoteEJBClient.START: Failed t
o start service
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1767) [jboss-msc-1.0.2.G
A.jar:1.0.2.GA]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0]
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0]
Caused by: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance
at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:163)
at org.jboss.as.ee.component.BasicComponent.createInstance(BasicComponent.java:85)
at org.jboss.as.ejb3.component.singleton.SingletonComponent.getComponentInstance(SingletonComponent.java:116)
at org.jboss.as.ejb3.component.singleton.SingletonComponent.start(SingletonComponent.java:130)
at org.jboss.as.ee.component.ComponentStartService.start(ComponentStartService.java:44)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-ms
c-1.0.2.GA.jar:1.0.2.GA]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.G
A.jar:1.0.2.GA]
... 3 more
Caused by: javax.ejb.EJBException: java.lang.IllegalStateException: No EJB receiver available for handling [appName:jbos
s-as-ejb-remote-server-ear-7.1.1-SNAPSHOT,modulename:jboss-as-ejb-remote-server-side-7.1.1-SNAPSHOT,distinctname:] combi
nation for invocation context org.jboss.ejb.client.EJBClientInvocationContext@5df95758
at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:166)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:230)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.requiresNew(CMTTxInterceptor.java:333)
at org.jboss.as.ejb3.tx.SingletonLifecycleCMTTxInterceptor.processInvocation(SingletonLifecycleCMTTxInterceptor.
java:56)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.ja
r:1.1.1.Final]
at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocat
ionContextInterceptor.java:41)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.ja
r:1.1.1.Final]
at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.ja
r:1.1.1.Final]
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation-1.1.1
.Final.jar:1.1.1.Final]
at org.jboss.as.ee.component.BasicComponent.constructComponentInstance(BasicComponent.java:161)
... 9 more
Caused by: java.lang.IllegalStateException: No EJB receiver available for handling [appName:jboss-as-ejb-remote-server-e
ar-7.1.1-SNAPSHOT,modulename:jboss-as-ejb-remote-server-side-7.1.1-SNAPSHOT,distinctname:] combination for invocation co
ntext org.jboss.ejb.client.EJBClientInvocationContext@5df95758
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:584)
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:119)
at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:136)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:121)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:104)
at $Proxy15.getTest(Unknown Source) at org.jboss.as.quickstarts.ejb.remote.client.RemoteEJBClient.invokeStat
elessBean(RemoteEJBClient.java:100)
at org.jboss.as.quickstarts.ejb.remote.client.RemoteEJBClient.initialize(RemoteEJBClient.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0]
at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0]
at org.jboss.as.ee.component.ManagedReferenceLifecycleMethodInterceptorFactory$ManagedReferenceLifecycleMethodIn
terceptor.processInvocation(ManagedReferenceLifecycleMethodInterceptorFactory.java:130)
....
So despite the fact that I'm making a successful handshake, I still get java.lang.IllegalStateException: No EJB receiver available for handling exception.
I have read over the forums and in most cases when people are getting this error the answer is that you don't have jboss-ejb-client.properties in the classpath.
I tried putting it in the client ejb's resouce folder, and then tried the ear's META-INF folder. I was analyzing traffic to and from my remote jboss server using tcpdump and
didn't see any traffic when putting the jboss-ejb-client.properties file in these places which should be in the class path. When I heard about setting the location of jboss-ejb-client.properties file
directly in standalone.conf.bat file, and configured it as shown above, THEN i noticed traffic from my local computer to my remote host and that is when I started getting that handshake succeeded log in my local
Jboss's logs, So I know that Jboss is reading the jboss-ejb-client.properties file.
Here is the output of the tcpdump on my remote server:
14:20:44.490284 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [S], seq 1491737537, win 8192, options [mss 1300,nop,wscale 8,nop,nop,sackOK], length 0
14:20:44.490336 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [S.], seq 612557719, ack 1491737538, win 14600, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 0
14:20:44.490610 IP asdeveug02.eug.realserver.net.36231 > ds02.hq.realserver.net.domain: 40177+ PTR? 12.255.20.10.in-addr.arpa. (43)
14:20:44.491871 IP ds02.hq.realserver.net.domain > asdeveug02.eug.realserver.net.36231: 40177* 1/0/0 PTR davidpugh-pc.hq.realserver.net. (83)
14:20:44.535948 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [.], ack 1, win 258, length 0
14:20:44.537237 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 1:33, ack 1, win 115, length 32
14:20:44.586061 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [P.], seq 1:43, ack 33, win 258, length 42
14:20:44.586078 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [.], ack 43, win 115, length 0
14:20:44.587362 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 33:83, ack 43, win 115, length 50
14:20:44.709354 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [P.], seq 43:66, ack 83, win 258, length 23
14:20:44.711828 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 83:138, ack 66, win 115, length 55
14:20:44.757830 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [P.], seq 66:108, ack 138, win 258, length 42
14:20:44.758855 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 138:188, ack 108, win 115, length 50
14:20:44.810129 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [P.], seq 108:124, ack 188, win 258, length 16
14:20:44.810731 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 188:299, ack 124, win 115, length 111
14:20:44.857514 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [P.], seq 124:409, ack 299, win 257, length 285
14:20:44.858277 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 299:344, ack 409, win 123, length 45
14:20:44.914044 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [P.], seq 409:450, ack 344, win 257, length 41
14:20:44.914218 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 344:364, ack 450, win 123, length 20
14:20:44.914512 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 364:385, ack 450, win 123, length 21
14:20:44.914563 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 385:397, ack 450, win 123, length 12
14:20:44.958191 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [.], ack 385, win 257, length 0
14:20:44.963079 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [P.], seq 450:465, ack 397, win 257, length 15
14:20:44.969504 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [P.], seq 465:485, ack 397, win 257, length 20
14:20:44.969559 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [.], ack 485, win 123, length 0
14:20:44.969670 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [P.], seq 485:497, ack 397, win 257, length 12
14:20:44.970136 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 397:412, ack 497, win 123, length 15
14:20:44.971039 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 412:619, ack 497, win 123, length 207
14:20:44.971085 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 619:631, ack 497, win 123, length 12
14:20:44.971236 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 631:643, ack 497, win 123, length 12
14:20:44.971279 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 643:655, ack 497, win 123, length 12
14:20:44.971373 IP asdeveug02.eug.realserver.net.n1-rmgmt > davidpugh-pc.hq.realserver.net.60729: Flags [P.], seq 655:666, ack 497, win 123, length 11
14:20:45.015935 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [.], ack 619, win 256, length 0
14:20:45.016913 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [.], ack 666, win 256, length 0
14:20:45.017096 IP davidpugh-pc.hq.realserver.net.60729 > asdeveug02.eug.realserver.net.n1-rmgmt: Flags [P.], seq 497:512, ack 666, win 256, length 15
Here is my client ejb class that was created by Jaikiran Pai originally and packaged as an executable jar originally, but I changed to an ejb within an ear that has an @Startup annotation and a @PostConstruct annotation that
assures that the class is started and run at startup.
/**
* A sample program which acts a remote client for a EJB deployed on AS7 server.
* This program shows how to lookup stateful and stateless beans via JNDI and then invoke on them
*
* @author Jaikiran Pai
*/
@Startup
@Singleton
public class RemoteEJBClient {
// The EJB invocation happens via the JBoss Remoting project, which uses SASL for
// authentication for client-server authentication. There are various different security algorithms that
// SASL supports. In this example we use "anonymous" access to the server and for that we register
// the JBossSaslProvider which provides support for that algorithm. Depending on how which algorithm
// is used, this piece of code to register JBossSaslProvider, may or may not be required
static {
Security.addProvider(new JBossSaslProvider());
}
/*
public static void main(String[] args) throws Exception {
// Invoke a stateless bean
invokeStatelessBean();
// Invoke a stateful bean
invokeStatefulBean();
}
*/
@PostConstruct
public void initialize() {
try {
invokeStatelessBean();
} catch (NamingException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
// Invoke a stateful bean
try {
invokeStatefulBean();
} catch (NamingException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
/**
* Looks up a stateless bean and invokes on it
*
* @throws NamingException
*/
private static void invokeStatelessBean() throws NamingException {
// Let's lookup the remote stateless calculator
final RemoteCalculator statelessRemoteCalculator = lookupRemoteStatelessCalculator();
System.out.println("Obtained a remote stateless calculator for invocation");
// invoke on the remote calculator
int a = 204;
int b = 340;
System.out.println("Adding " + a + " and " + b + " via the remote stateless calculator deployed on the server");
Integer output = statelessRemoteCalculator.getTest();
System.out.println("testing:" + output.toString());
int sum = statelessRemoteCalculator.add(a, b);
System.out.println("Remote calculator returned sum = " + sum);
if (sum != a + b) {
throw new RuntimeException("Remote stateless calculator returned an incorrect sum " + sum + " ,expected sum was " + (a + b));
}
// try one more invocation, this time for subtraction
int num1 = 3434;
int num2 = 2332;
System.out.println("Subtracting " + num2 + " from " + num1 + " via the remote stateless calculator deployed on the server");
int difference = statelessRemoteCalculator.subtract(num1, num2);
System.out.println("Remote calculator returned difference = " + difference);
if (difference != num1 - num2) {
throw new RuntimeException("Remote stateless calculator returned an incorrect difference " + difference + " ,expected difference was " + (num1 - num2));
}
}
/**
* Looks up a stateful bean and invokes on it
*
* @throws NamingException
*/
private static void invokeStatefulBean() throws NamingException {
// Let's lookup the remote stateful counter
final RemoteCounter statefulRemoteCounter = lookupRemoteStatefulCounter();
System.out.println("Obtained a remote stateful counter for invocation");
// invoke on the remote counter bean
final int NUM_TIMES = 5;
System.out.println("Counter will now be incremented " + NUM_TIMES + " times");
for (int i = 0; i < NUM_TIMES; i++) {
System.out.println("Incrementing counter");
statefulRemoteCounter.increment();
System.out.println("Count after increment is " + statefulRemoteCounter.getCount());
}
// now decrementing
System.out.println("Counter will now be decremented " + NUM_TIMES + " times");
for (int i = NUM_TIMES; i > 0; i--) {
System.out.println("Decrementing counter");
statefulRemoteCounter.decrement();
System.out.println("Count after decrement is " + statefulRemoteCounter.getCount());
}
}
/**
* Looks up and returns the proxy to remote stateless calculator bean
*
* @return
* @throws NamingException
*/
private static RemoteCalculator lookupRemoteStatelessCalculator() throws NamingException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);
// The JNDI lookup name for a stateless session bean has the syntax of:
// ejb:<appName>/<moduleName>/<distinctName>/<beanName>!<viewClassName>
//
// <appName> The application name is the name of the EAR that the EJB is deployed in
// (without the .ear). If the EJB JAR is not deployed in an EAR then this is
// blank. The app name can also be specified in the EAR's application.xml
//
// <moduleName> By the default the module name is the name of the EJB JAR file (without the
// .jar suffix). The module name might be overridden in the ejb-jar.xml
//
// <distinctName> : AS7 allows each deployment to have an (optional) distinct name.
// This example does not use this so leave it blank.
//
// <beanName> : The name of the session been to be invoked.
//
// <viewClassName>: The fully qualified classname of the remote interface. Must include
// the whole package name.
// let's do the lookup
return (RemoteCalculator) context.lookup(
"ejb:jboss-as-ejb-remote-server-ear-7.1.1-SNAPSHOT/jboss-as-ejb-remote-server-side-7.1.1-SNAPSHOT/CalculatorBean!org.jboss.as.quickstarts.ejb.remote.stateless.RemoteCalculator"
);
}
/**
* Looks up and returns the proxy to remote stateful counter bean
*
* @return
* @throws NamingException
*/
private static RemoteCounter lookupRemoteStatefulCounter() throws NamingException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
final Context context = new InitialContext(jndiProperties);
// The JNDI lookup name for a stateful session bean has the syntax of:
// ejb:<appName>/<moduleName>/<distinctName>/<beanName>!<viewClassName>?stateful
//
// <appName> The application name is the name of the EAR that the EJB is deployed in
// (without the .ear). If the EJB JAR is not deployed in an EAR then this is
// blank. The app name can also be specified in the EAR's application.xml
//
// <moduleName> By the default the module name is the name of the EJB JAR file (without the
// .jar suffix). The module name might be overridden in the ejb-jar.xml
//
// <distinctName> : AS7 allows each deployment to have an (optional) distinct name.
// This example does not use this so leave it blank.
//
// <beanName> : The name of the session been to be invoked.
//
// <viewClassName>: The fully qualified classname of the remote interface. Must include
// the whole package name.
// let's do the lookup
return (RemoteCounter) context.lookup(
"ejb:jboss-as-ejb-remote-server-ear-7.1.1-SNAPSHOT/jboss-as-ejb-remote-server-side-7.1.1-SNAPSHOT/CounterBean!org.jboss.as.quickstarts.ejb.remote.stateful.RemoteCounter?stateful"
);
}
}
Here is my jboss-ejb-client.properties file:
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=asdeveug02.eug.realserver.net
remote.connection.default.port =4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.username=davidpugh
remote.connection.default.password=realserver55
I have setup application-user.properties with an ApplicationRealm that has davidpugh as the user and password "realserver55" with "guest" as a role
Please help me, as this remote ejb lookup should be REALLY EASY, and the jboss upgrade (we were using 4.2.3 before) is turning into a nightmare.
Thank you.