How to set EJB client side invocation timeout in JBoss EAP 7.1
Environment
- Red Hat Enterprise Application Platform (EAP)
- 7.1+
Issue
- How to set EJB client side invocation timeout in JBoss EAP 7.1?
Resolution
The EJB Invocation timeout can be set using EJBClient.setInvocationTimeout or by setting invocation.timeout in the InitialContext properties.
Note: if the server does not send the EJB response in the specified invocation timeout, the client will be thrown an EJBException but the server will continue to process the request until done.
See the examples below.
import org.jboss.ejb.client.EJBClient;
public void callRemoteEjb() {
HelloRemote remote = new getInitialContext(host, port, user, pass).lookup("ejb:helloWorld/helloWorld-ejb/HelloWorldSLSB!org.jboss.examples.ejb.HelloRemote");
EJBClient.setInvocationTimeout(remote, 10, TimeUnit.SECONDS);
try {
remote.helloWorld();
} catch(javax.ejb.EJBException e) {
// if the EJB response is not received within the specified timeout, this exception will be thrown:
// javax.ejb.EJBException: java.util.concurrent.TimeoutException: No invocation response received in 10000 milliseconds
}
}
public static Context getInitialContext(String host, Integer port, String username, String password) {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
props.put(Context.PROVIDER_URL, String.format("%s://%s:%d", "remote+http", host, port));
props.put(Context.SECURITY_PRINCIPAL, username)
props.put(Context.SECURITY_CREDENTIALS, password);
return new InitialContext(props);
}
The invocation timeout can also be set by specifying the property on the InitialContext during its creation such as:
props.put("invocation.timeout", 10000);
If the remote EJB call is server-to-server style with WEB-INF/jboss-ejb-client.xml, the invocation-timeout can be set in jboss-ejb-client.xml:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-ejb-client xmlns="urn:jboss:ejb-client:1.2">
<client-context invocation-timeout="10000">
<ejb-receivers>
<remoting-ejb-receiver outbound-connection-ref="remote-ejb-connection"/>
</ejb-receivers>
</client-context>
</jboss-ejb-client>
If the EJB invocation does not return in the specified invocation timeout, the client will be thrown an EJBException as shown in the example below.
javax.ejb.EJBException: java.util.concurrent.TimeoutException: No invocation response received in 10000 milliseconds
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:204)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:107)
at com.sun.proxy.$Proxy2.sleep(Unknown Source)
at org.jboss.reproducer.test.TestClient.testWildflyNamingInvocationTimeout(TestClient.java:112)
at org.jboss.reproducer.test.TestClient.main(TestClient.java:51)
Caused by: java.util.concurrent.TimeoutException: No invocation response received in 1000 milliseconds
at org.jboss.ejb.client.EJBClientInvocationContext.lambda$awaitResponse$3(EJBClientInvocationContext.java:892)
at org.jboss.ejb.client.EJBClientInvocationContext$ThrowableResult.getResult(EJBClientInvocationContext.java:1147)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:570)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:507)
at org.jboss.ejb.protocol.remote.RemotingEJBClientInterceptor.handleInvocationResult(RemotingEJBClientInterceptor.java:56)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:572)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:507)
at org.jboss.ejb.client.DiscoveryEJBClientInterceptor.handleInvocationResult(DiscoveryEJBClientInterceptor.java:98)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:572)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:507)
at org.jboss.ejb.client.NamingEJBClientInterceptor.handleInvocationResult(NamingEJBClientInterceptor.java:49)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:572)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:507)
at org.jboss.ejb.client.TransactionInterceptor.handleInvocationResult(TransactionInterceptor.java:86)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:572)
at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:507)
at org.jboss.ejb.client.EJBClientInvocationContext.awaitResponse(EJBClientInvocationContext.java:929)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:174)
... 4 more
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.