Remote EJB Client Channel Closed Errors
jfisherdev May 16, 2017 2:16 PMWe have been encountering the exception below seemingly at random.
java.rmi.RemoteException: Error; nested exception is: java.io.IOException: Channel Channel ID d1a61663 (outbound) of Remoting connection 20b68fcb to $hostname$/$hostIp$:$http.port$ has been closed //Invoke Remote EJB interface here Caused by: java.rmi.RemoteException: Error; nested exception is: java.io.IOException: Channel Channel ID d1a61663 (outbound) of Remoting connection 20b68fcb to $hostname$/$hostIp$:$http.port$ has been closed at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:236) at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:183) at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146) at com.sun.proxy.$Proxy2.invoke(Unknown Source) at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) ... 10 more Caused by: java.io.IOException: Channel Channel ID d1a61663 (outbound) of Remoting connection 20b68fcb to $hostname$/$hostIp$:$http.port$ has been closed at org.jboss.ejb.client.remoting.ChannelAssociation$1.handleClose(ChannelAssociation.java:123) at org.jboss.ejb.client.remoting.ChannelAssociation$1.handleClose(ChannelAssociation.java:115) at org.jboss.remoting3.spi.SpiUtils.safeHandleClose(SpiUtils.java:54) at org.jboss.remoting3.spi.AbstractHandleableCloseable$CloseHandlerTask.run(AbstractHandleableCloseable.java:514) at org.jboss.remoting3.spi.AbstractHandleableCloseable.runCloseTask(AbstractHandleableCloseable.java:419) at org.jboss.remoting3.spi.AbstractHandleableCloseable.closeComplete(AbstractHandleableCloseable.java:290) at org.jboss.remoting3.remote.RemoteConnectionChannel.closeAction(RemoteConnectionChannel.java:543) at org.jboss.remoting3.spi.AbstractHandleableCloseable.closeAsync(AbstractHandleableCloseable.java:372) at org.jboss.remoting3.remote.RemoteConnectionHandler.closeAllChannels(RemoteConnectionHandler.java:429) at org.jboss.remoting3.remote.RemoteConnectionHandler.sendCloseRequest(RemoteConnectionHandler.java:233) at org.jboss.remoting3.remote.RemoteConnectionHandler.handleConnectionClose(RemoteConnectionHandler.java:113) at org.jboss.remoting3.remote.RemoteReadListener$1$1.run(RemoteReadListener.java:56) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
The call is being made from a remote standalone EJB client [a Swing GUI application] to a standalone WildFly 9.0.2.final server.
An approximation of the classes we use to facilitate making the remote invocation as well as the call itself are as follows.
//Wraps a Context object to simplify the lookup public class EjbClient implements AutoCloseable { private final Context context; public EjbClient(Context context) { this.context = context; } //Other lookup helper operations public Object lookupEJB(String jndiName) throws NamingException { return context.lookup(jndiName); } @Override//from AutoCloseable public void close() throws Exception { context.close(); } }
//Singleton object that maintains EjbClient instances for the lifetime of the application public EjbClientFactory { public static EjbClientFactory getInstance(){ ... } //Default client/context for this application private EjbClient defaultClient; //EjbClients/contexts for this client to communicate with other applications/servers private final Map<String, EjbClient> otherAppClients = new ConcurrentHashMap<>(); public EjbClient getDefaultClient() throws NamingException { if(defaultClient == null) { defaultClient = new InitialContext(createProperties()); } return defaultClient; } public EjbClient getClientForApp(String app) { if(otherAppClients.containsKey(app){ return otherAppClients.get(app); } final Properties appClientProperties = createProperties(); //Add/adjust app-specific properties as needed final EjbClient appClient = new EjbClient(new InitialContext(appClientProperties)); otherAppClients.put(app, appClient); return appClient; } private Properties createProperties() { //Create properties for scoped EJB client context, relevant properties given below: //java.naming.factory.url.pkgs = org.jboss.ejb.client.naming //connect.options.org.jboss.remoting3.RemotingOptions.HEARTBEAT_INTERVAL = 60000 //channel.options.org.jboss.remoting3.RemotingOptions.MAX_INBOUND_MESSAGES = 80 //channel.options.org.jboss.remoting3.RemotingOptions.MAX_OUTBOUND_MESSAGES = 80 //org.jboss.ejb.clint.scoped.context = true } }
//The Swing client that makes the remote EJB calls. public class AppGuiClient { private Runnable updateAlertsRunnable = new Runnable() { @Override public void run() { updateAlerts(); } } void refresh() { //The < Java 5 way of doing the fetch on a separate thread was already there and not my idea final Thread updateAlertsThread = new Thread(updateAlertsRunnable); updateAlertsThread.setDaemon(true); updateAlertsThread.start(); } private void updateAlerts() { try { final EjbClient ejbClient = EjbClientFactory.getInstance().getDefaultClient(); //Stateless session bean remote interface final AlertSessionRemote remote = (AlertSessionRemote) ejbClient.lookup(...); //JNDI lookup is fine, it SOMETIMES fails here when invoking the remote proxy final List<Alert> alerts = remote.getAlerts(); //Update GUI with alert information addAlerts(alerts); } catch (Exception e) { //Show a dialog with exception details, the same happens for uncaught exceptions displayException(e); } } }
I don't understand how this state and exception are being reached and that this only occurs sometimes with this method. The client context is not closed between invocations [not closed until the application is finished with them], which would make sense, but isn't the case here. Also, subsequent calls with the same client/context work, which makes this more confusing.
Is there client or server-side configuration that might be a problem? The only areas I could think of on the server-side would be XNIO or remoting.
Any information or ideas about this would be appreciated greatly.