简体   繁体   中英

JMS : Closing naming context fails

This code throw an exception in context.close() :

final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, org.jboss.naming.remote.client.InitialContextFactory.class.getName());
env.put(Context.PROVIDER_URL, PROVIDER_URL);
env.put(Context.SECURITY_PRINCIPAL, DEFAULT_USERNAME);
env.put(Context.SECURITY_CREDENTIALS, DEFAULT_PASSWORD);
env.put("jboss.naming.client.ejb.context", true);
env.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
context = new InitialContext(env);

// lookup for RemoteConnectionFactory works fine, JMS Desitination found, JMS queue works also
// JMS connection, producer and consumer created successfully... 
context.close(); // Exception

ERROR: Close handler threw an exception
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@61796307 rejected from java.util.concurrent.ThreadPoolExecutor@6854928f[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:110)
    at org.jboss.ejb.client.EJBClientContext.unregisterEJBReceiver(EJBClientContext.java:440)
    at org.jboss.ejb.client.EJBReceiverContext.close(EJBReceiverContext.java:57)
    at org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver$1$1.handleClose(RemotingConnectionEJBReceiver.java:181)
    at org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver$1$1.handleClose(RemotingConnectionEJBReceiver.java:178)
    at org.jboss.remoting3.spi.SpiUtils.safeHandleClose(SpiUtils.java:54)
    at org.jboss.remoting3.spi.AbstractHandleableCloseable$CloseHandlerTask.run(AbstractHandleableCloseable.java:501)
    at org.jboss.remoting3.spi.AbstractHandleableCloseable.runCloseTask(AbstractHandleableCloseable.java:406)
    at org.jboss.remoting3.spi.AbstractHandleableCloseable.closeComplete(AbstractHandleableCloseable.java:277)
    at org.jboss.remoting3.remote.RemoteConnectionChannel.closeAction(RemoteConnectionChannel.java:531)
    at org.jboss.remoting3.spi.AbstractHandleableCloseable.closeAsync(AbstractHandleableCloseable.java:359)
    at org.jboss.remoting3.remote.RemoteConnectionHandler.closeAllChannels(RemoteConnectionHandler.java:401)
    at org.jboss.remoting3.remote.RemoteConnectionHandler.sendCloseRequest(RemoteConnectionHandler.java:233)
    at org.jboss.remoting3.remote.RemoteConnectionHandler.closeAction(RemoteConnectionHandler.java:387)
    at org.jboss.remoting3.spi.AbstractHandleableCloseable.closeAsync(AbstractHandleableCloseable.java:359)
    at org.jboss.remoting3.ConnectionImpl.closeAction(ConnectionImpl.java:52)
    at org.jboss.remoting3.spi.AbstractHandleableCloseable.closeAsync(AbstractHandleableCloseable.java:359)
    at org.jboss.remoting3.EndpointImpl.closeAction(EndpointImpl.java:203)
    at org.jboss.remoting3.spi.AbstractHandleableCloseable.close(AbstractHandleableCloseable.java:153)
    at org.jboss.naming.remote.client.EndpointCache.release(EndpointCache.java:67)
    at org.jboss.naming.remote.client.EndpointCache$EndpointWrapper.close(EndpointCache.java:183)
    at org.jboss.naming.remote.client.InitialContextFactory$1.close(InitialContextFactory.java:233)
    at org.jboss.naming.remote.client.RemoteContext.close(RemoteContext.java:237)
    at javax.naming.InitialContext.close(InitialContext.java:550)
    at sample.HelloWorldJMSClient.main(HelloWorldJMSClient.java:104)

The close of the context is handed off as an asynchronous task to a ThreadPoolExecutor. However, the ThreadPoolExecutor has been terminated and rejects the task. It's not clear to me why the pool would have been terminated, but my guess is that there is a shutdown in progress (or a bug ?).

I would imagine that the resources allocated by the context would be cleaned up eventually anyways, so the only recommendation I can make is that you always close your context in code wrapped in a try/catch withing the finally block of your method.

public ConnectionFactory getConnectionFactory() {
   Context context = null;
   try {
      // create context here
      // lookup here
      // return ConnFactory here
   } catch (Exception e) {
      // log error, throw exception etc.
   } finally {
      if(context!=null) try { context.close(); } catch (Exception ex} { /* No Op */ }
   }
}

For JNDI contexts this is usually legit since there is nothing you can do about a failed close and there is no point failing after an otherwise successful operation. Moreover, if there is a serious issue in the JNDI service (such as the async thread pools spuriously being terminated) I would think the exact symptoms and diagnosis would be available and visible elsewhere. I would not pollute this otherwise simple code with anything else.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM