diff --git a/CHANGES.txt b/CHANGES.txt index 2ea3af23e4..00d8599dd4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -373,6 +373,9 @@ Trunk (unreleased changes) HADOOP-6719. Insert all missing methods in FilterFs. (Rodrigo Schmidt via dhruba) + HADOOP-6724. IPC doesn't properly handle IOEs thrown by socket factory. + (Todd Lipcon via tomwhite) + Release 0.21.0 - Unreleased INCOMPATIBLE CHANGES diff --git a/src/java/org/apache/hadoop/ipc/Client.java b/src/java/org/apache/hadoop/ipc/Client.java index a20865ff8c..a7c25d3b9c 100644 --- a/src/java/org/apache/hadoop/ipc/Client.java +++ b/src/java/org/apache/hadoop/ipc/Client.java @@ -494,10 +494,12 @@ public Boolean run() throws IOException { private void handleConnectionFailure( int curRetries, int maxRetries, IOException ioe) throws IOException { // close the current connection - try { - socket.close(); - } catch (IOException e) { - LOG.warn("Not able to close a socket", e); + if (socket != null) { + try { + socket.close(); + } catch (IOException e) { + LOG.warn("Not able to close a socket", e); + } } // set socket to null so that the next call to setupIOstreams // can start the process of connect all over again. diff --git a/src/test/core/org/apache/hadoop/ipc/TestIPC.java b/src/test/core/org/apache/hadoop/ipc/TestIPC.java index 16e1cbe576..f41894df22 100644 --- a/src/test/core/org/apache/hadoop/ipc/TestIPC.java +++ b/src/test/core/org/apache/hadoop/ipc/TestIPC.java @@ -29,8 +29,10 @@ import java.io.DataInput; import java.io.IOException; import java.net.InetSocketAddress; +import javax.net.SocketFactory; import junit.framework.TestCase; +import static org.mockito.Mockito.*; import org.apache.hadoop.conf.Configuration; @@ -267,6 +269,25 @@ public void testErrorClient() throws Exception { } } + /** + * Test that, if the socket factory throws an IOE, it properly propagates + * to the client. + */ + public void testSocketFactoryException() throws Exception { + SocketFactory mockFactory = mock(SocketFactory.class); + doThrow(new IOException("Injected fault")).when(mockFactory).createSocket(); + Client client = new Client(LongWritable.class, conf, mockFactory); + + InetSocketAddress address = new InetSocketAddress("127.0.0.1", 10); + try { + client.call(new LongWritable(RANDOM.nextLong()), + address, null, null); + fail("Expected an exception to have been thrown"); + } catch (IOException e) { + assertTrue(e.getMessage().contains("Injected fault")); + } + } + public static void main(String[] args) throws Exception {