Archived

This forum has been archived. Please start a new discussion on GitHub.

How to handle java.lang.Thread.interrupt() in a safe way?

Hello everyone,

we have the following problem:

Our Client (java) calls an operation on the server (c++). This call takes several seconds to complete at the server. While the call is running the thread on the client, which is executing the call receives a java.lang.Thread.interrupt().

This interrupts the blocking network operation on the client:

[oth ] ERROR 2008-06-10 12:46:59,968 exception in `Ice.ThreadPool.Client' thread Ice.ThreadPool.Client-2:
Ice.SocketException
error = 0
at IceInternal.TcpTransceiver.shutdownWrite(TcpTransceiver.java:104)
at Ice.ConnectionI.setState(ConnectionI.java:1864)
at Ice.ConnectionI.setState(ConnectionI.java:1722)
at Ice.ConnectionI.exception(ConnectionI.java:1443)
at IceInternal.ThreadPool.run(ThreadPool.java:745)
at IceInternal.ThreadPool.access$100(ThreadPool.java:12)
at IceInternal.ThreadPool$EventHandlerThread.run(ThreadPool.java:1242)
Caused by: java.nio.channels.ClosedChannelException
at sun.nio.ch.SocketChannelImpl.shutdownOutput(SocketChannelImpl.java:649)
at sun.nio.ch.SocketAdaptor.shutdownOutput(SocketAdaptor.java:368)
at IceInternal.TcpTransceiver.shutdownWrite(TcpTransceiver.java:87)
... 6 more
- [Ice.ThreadPool.Client-2] (IceLogger.java:26)

The bad new is, that this somehow breaks the clientside threadpool. All further invokes of remote calls will throw the following exception:

[oth ] ERROR 2008-06-10 12:46:59,970 unknown exception in `Ice.ThreadPool.Client' thread Ice.ThreadPool.Client-1:
java.util.NoSuchElementException
at java.util.LinkedList.remove(LinkedList.java:788)
at java.util.LinkedList.removeFirst(LinkedList.java:134)
at IceInternal.ThreadPool.run(ThreadPool.java:551)
at IceInternal.ThreadPool.access$100(ThreadPool.java:12)
at IceInternal.ThreadPool$EventHandlerThread.run(ThreadPool.java:1242)
- [Ice.ThreadPool.Client-1] (IceLogger.java:26)


I have been looking for a solution in the docs and the forum, but I'm not able to find a solution.

Any ideas?

Best regards,
Markus

Comments

  • mes
    mes California
    Hi Markus,

    Ice for Java does not currently support the use of Thread.interrupt. Out of curiosity, why is this method being called?

    Take care,
    Mark
  • Hi mes,

    short answer:
    I have no control over the call to Thread.interrupt().

    long answer:
    I use ICE to communicate to our database-server. It has an JDBC-like API. The user of my API do not know they are using ICE. They integrate my jar-archive and use my interface classes to connect to the database.

    What the user is doing to the thread that calls my API methods I cannot control. In my case the driver is used in an ApplicationServer which has an ThreadManager which uses Thread.interrupt() to cancel stalled processes.

    IMHO it's a bug in ICE not to handle Thread.interrupt(). AFAIK the java specification states that any thread has to be prepared to receive an interrupt at any time, because you simply cannot control it. Even if the whole application has no call to Thread.interrupt it still can happen that the JVM interrupts a thread. Thats the reason why the class InterruptedException is derived from Exception and not from RuntimeException and is enforced to be handled by the compiler.

    To be honest I'm not completely sure this holds to be true for IO-operations, because otherwise this should have come up before by someone else. But if your using the classic example and call Thread.sleep(1000) in a endless loop and run the program for some time you will see it will happen.

    At the moment I'm not sure what to do. Some things that came to my mind:
    - Try to handle the InterruptedException by myself
    - Look into AMI/AMD. Will that fix it?
    - Look into ICE and patch it.

    Best regards and many thanks for all answers
    Markus
  • mes
    mes California
    Hi Markus,

    This is a known issue in Ice for Java. Can you tell us more about the environment, including the versions of the JVM and Ice?

    Thanks,
    Mark
  • bernard
    bernard Jupiter, FL
    Hi Markus,

    I think a good work-around for this issue would be to use AMI for this long-running call, i.e. something like:
    * you send the request with AMI and wait on the AMI callback object
    * when the callback receives the response (from a thread in the Ice client thread-pool), it notifies your waiting thread.
    * if this waiting thread is interrupted, it just returns; when the response is eventually delivered, it will be ignored

    Cheers,
    Bernard