JMS:关闭命名上下文失败

时间:2014-07-24 11:10:37

标签: java jboss jms handler jndi

此代码在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)

1 个答案:

答案 0 :(得分:1)

上下文的关闭作为异步任务传递给ThreadPoolExecutor。但是,ThreadPoolExecutor已终止并拒绝该任务。我不清楚为什么池会被终止,但我的猜测是正在关机(或者是一个bug?)。

我认为上下文分配的资源最终会被清理掉,所以我唯一可以建议的是你总是在try / catch包含的代码中用你方法的finally块关闭你的上下文。

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 */ }
   }
}

对于JNDI上下文,这通常是合法的,因为关于失败的关闭没有什么可以做的,并且在其他成功的操作之后没有任何意义上的失败。此外,如果JNDI服务中存在严重问题(例如异步线程池被虚假终止),我认为确切的症状和诊断将可用并在其他地方可见。我不会用其他任何东西污染这个简单的代码。