Return-Path: Delivered-To: apmail-ws-general-archive@www.apache.org Received: (qmail 32669 invoked from network); 28 Feb 2008 13:22:47 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 28 Feb 2008 13:22:47 -0000 Received: (qmail 4297 invoked by uid 500); 28 Feb 2008 13:22:42 -0000 Delivered-To: apmail-ws-general-archive@ws.apache.org Received: (qmail 3665 invoked by uid 500); 28 Feb 2008 13:22:40 -0000 Mailing-List: contact general-help@ws.apache.org; run by ezmlm Precedence: bulk Reply-To: general@ws.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list general@ws.apache.org Received: (qmail 3654 invoked by uid 99); 28 Feb 2008 13:22:40 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 28 Feb 2008 05:22:40 -0800 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.130] (HELO eos.apache.org) (140.211.11.130) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 28 Feb 2008 13:22:15 +0000 Received: from eos.apache.org (localhost [127.0.0.1]) by eos.apache.org (Postfix) with ESMTP id DE22CD2DB for ; Thu, 28 Feb 2008 13:22:24 +0000 (GMT) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Apache Wiki To: general@ws.apache.org Date: Thu, 28 Feb 2008 13:22:24 -0000 Message-ID: <20080228132224.24405.11690@eos.apache.org> Subject: [Ws Wiki] Update of "FrontPage/Axis/AxisClientConfiguration/InterruptCalls" by RodrigoRuiz X-Virus-Checked: Checked by ClamAV on apache.org Dear Wiki user, You have subscribed to a wiki page or wiki category on "Ws Wiki" for change notification. The following page has been changed by RodrigoRuiz: http://wiki.apache.org/ws/FrontPage/Axis/AxisClientConfiguration/InterruptCalls The comment on the change is: First draft, comments welcome. New page: = How do I interrupt a thread that is blocked in a remote call in Axis 1.4? = If you have ever tried to, you may know that a thread performing a blocking I/O operation cannot be interrupted in Java. The problem lies in the JVM itself, and comes from the ages of Java 1.1. There are several bugs open in java.sun, and it looks like this behaviour [http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4385444 is here to stay]. There are two workarounds for this issue: * Use the new java.nio classes, and InterruptibleChannel in particular. * Close the stream. This will force the blocking operation to be cancelled. Well, porting Axis 1.4 to Java NIO does not look like the way to go so, let's take a look at the second option. The following is a subclass of HTTPSender that will allow us to close the socket (and hence its associated streams): {{{ package org.apache.axis.transport.http; import java.io.IOException; import java.net.Socket; import java.net.SocketException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.axis.AxisFault; import org.apache.axis.MessageContext; import org.apache.axis.components.net.BooleanHolder; /** * HTTPSender modified to allow interruption during I/O read. */ public class InterruptibleHttpSender extends HTTPSender { private static final ConcurrentMap SOCKETS = new ConcurrentHashMap(); /** * Interrupts the specified thread operation by closing its associated socket. * * @param t The thread to interrupt */ public static void interrupt(Thread t) { Socket s = SOCKETS.get(t); if (s != null) { try { s.close(); } catch (IOException ignore) { } } } /** * {@inheritDoc} */ @Override public void invoke(MessageContext msgContext) throws AxisFault { try { super.invoke(msgContext); } catch (AxisFault fault) { Thread t = Thread.currentThread(); if (fault.getCause() instanceof SocketException && t.isInterrupted()) { fault = AxisFault.makeFault(new InterruptedException()); } throw fault; } finally { SOCKETS.remove(Thread.currentThread()); } } /** * {@inheritDoc} */ @Override protected void getSocket(SocketHolder sockHolder, MessageContext msgContext, String protocol, String host, int port, int timeout, StringBuffer otherHeaders, BooleanHolder useFullURL) throws Exception { super.getSocket(sockHolder, msgContext, protocol, host, port, timeout, otherHeaders, useFullURL); SOCKETS.put(Thread.currentThread(), sockHolder.getSocket()); } } }}} As you can see, I am using Java 5 ConcurrentMap to handle thread-safety. If you need to compile in Java 1.4, it can be replaced by a simple Hashtable. Now, to put this class to work we need to do two things: register it, and use it :-) For registering the class, we just need to modify the client-config.wsdd descriptor: {{{ }}} If this is not an option, there are [wiki:/AxisClientConfiguration other ways] to change the configuration. Unfortunately, this class is not magic. The interruption of the thread must be done manually by calling the {{{InterruptibleHttpSender#interrupt(Thread)}}} static method. This call should be done AFTER calling {{{Thread#interrupt()}}}, because it depends on the "isInterrupted" state of the thread to correctly handle exceptions. So, wherever you have a call to Thread.interrupt(), you should do something like: {{{ Thread t = ... t.interrupt(); InterruptibleHttpSender.interrupt(t); }}} This step can be partially automated by creating a custom Thread subclass: {{{ public abstract class AbstractAxisClientThread extends Thread { /** * {@inheritDoc} */ @Override public void interrupt() { super.interrupt(); InterruptibleHttpSender.interrupt(this); } } }}} and subclassing from it. --------------------------------------------------------------------- To unsubscribe, e-mail: general-unsubscribe@ws.apache.org For additional commands, e-mail: general-help@ws.apache.org