Question

I am using netty to connect and disconnect. But I get an exception when I try to disconnect, and I can't quite understand what causes it.

I have a global:

private ClientBootstrap bootstrap_;

When I try to connect I perform the following:

First initialization:

ChannelFactory channelFactory = null;
channelFactory = new OioClientSocketChannelFactory(Executors.newCachedThreadPool());
bootstrap_ = new ClientBootstrap(channelFactory);

Followed by:

    bootstrap_.setPipelineFactory(() -> {
    ChannelPipeline pipeline = Channels.pipeline();
        // SOME CODE
    });

    bootstrap_.setOption("remoteAddress", addr);
    bootstrap_.setOption("tcpNoDelay", true);
    bootstrap_.setOption("keepAlive", true);
    bootstrap_.setOption("configureBlocking", false);
    bootstrap_.setOption("connectTimeoutMillis", 5000);

And execute:

    bootstrap_.connect(addr);

Which does return success.

Shortly after I close all the channels and try executing:

bootstrap_.releaseExternalResources();

to stop the connection, and it returns an IllegalStateException thrown by ExecutorUtil.java

  "An Executor cannot be shut down from the thread " +
  "acquired from itself.  Please make sure you are " +
  "not calling releaseExternalResources() from an " +
  "I/O worker thread."

I have no idea why such an exception would be thrown and what exactly causes it to happen. Thanks in advance to any help, this issue is really bugging me.

Was it helpful?

Solution

The error message is telling you that you cannot call releaseExternalResources from a thread managed by an executor which, in itself, is managed by releaseExternalResources. It results in a deadlock because releaseExternalResources is trying to shutdown the executor which won't return until the thread that has called releaseExternalResources returns (which it can't).

I would guess that you're calling releaseExternalResources from a thread managed by the executor passed to OioClientSocketChannelFactory, possibly from within a handler. This won't work. You need to call it from a completely separate thread. One option is to block your main application thread until you're ready to shutdown, signal the application thread and have it call releaseExternalResources just before your application exits.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top