diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java b/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java index 6eebaf4d6ebb7..c89932924d06e 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java @@ -652,9 +652,10 @@ void cleanup(Control[] reqCtls, boolean notifyParent) { } } finally { - flushAndCloseOutputStream(); + flushOutputStream(); // 8313657 socket is not closed until GC is run - closeOpenedSocket(sock); + // due to the bug 8362268, the closure of the resource is moved to LdapClient.java + //closeOpenedSocket(sock); tryUnpauseReader(); if (!notifyParent) { @@ -673,7 +674,6 @@ void cleanup(Control[] reqCtls, boolean notifyParent) { tlsHandshakeListener.tlsHandshakeCompleted.cancel(false); } } - sock = null; } nparent = notifyParent; } @@ -693,19 +693,13 @@ void cleanup(Control[] reqCtls, boolean notifyParent) { } // flush and close output stream - private void flushAndCloseOutputStream() { + private void flushOutputStream() { try { outStream.flush(); } catch (IOException ioEx) { if (debug) System.err.println("Connection.flushOutputStream: OutputStream flush problem " + ioEx); } - try { - outStream.close(); - } catch (IOException ioEx) { - if (debug) - System.err.println("Connection.closeOutputStream: OutputStream close problem " + ioEx); - } } // close socket @@ -720,7 +714,26 @@ private void closeOpenedSocket(Socket socket) { } } } + void cleanupAndClose(Control[] reqCtls) { + lock.lock(); + try { + + cleanup(reqCtls, false); + // 8313657 socket is not closed until GC is run + // it caused the bug 8362268, hence moved here + if (outStream != null) { + outStream.close(); + } + if (!sock.isClosed()) { + sock.close(); + } + } catch (IOException ignored) { + // we're closing, ignore IO. + } finally { + lock.unlock(); + } + } // unpause reader private void tryUnpauseReader() { try { diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClient.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClient.java index 48f015d5393b7..afd3a7a1398c9 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClient.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClient.java @@ -460,12 +460,12 @@ void close(Control[] reqCtls, boolean hardClose) { if (debug > 0) System.err.println("LdapClient: closed connection " + this); if (!pooled) { // Not being pooled; continue with closing - conn.cleanup(reqCtls, false); + conn.cleanupAndClose(reqCtls); } else { // Pooled // Is this a real close or a request to return conn to pool if (hardClose) { - conn.cleanup(reqCtls, false); + conn.cleanupAndClose(reqCtls); pcb.removePooledConnection(this); } else { pcb.releasePooledConnection(this); @@ -477,6 +477,7 @@ void close(Control[] reqCtls, boolean hardClose) { } } + // NOTE: Should NOT be synchronized otherwise won't be able to close private void forceClose(boolean cleanPool) { referenceCount = 0; // force closing of connection diff --git a/test/jdk/com/sun/jndi/ldap/SocketCloseTest.java b/test/jdk/com/sun/jndi/ldap/SocketCloseTest.java index a33beb6caccb5..c5a421adcfcb6 100644 --- a/test/jdk/com/sun/jndi/ldap/SocketCloseTest.java +++ b/test/jdk/com/sun/jndi/ldap/SocketCloseTest.java @@ -27,11 +27,7 @@ import javax.net.SocketFactory; import java.net.InetAddress; import java.net.Socket; -import java.net.SocketAddress; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.Hashtable; import jdk.test.lib.process.OutputAnalyzer; @@ -65,6 +61,7 @@ public void runCloseSocketScenario() throws Exception { props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); props.put(Context.PROVIDER_URL, "ldap://localhost:1389/o=example"); props.put("java.naming.ldap.factory.socket", CustomSocketFactory.class.getName()); + props.put("com.sun.jndi.ldap.connect.timeout", 100+""); try { final DirContext ctx = new InitialDirContext(props); } catch (Exception e) { @@ -112,48 +109,8 @@ public Socket createSocket(InetAddress address, int port, } } - private static class LdapInputStream extends InputStream { - private ByteArrayInputStream bos; - - public LdapInputStream() { - } - - @Override - public int read() throws IOException { - bos = new ByteArrayInputStream(BIND_RESPONSE); - return bos.read(); - } - } - - private static class LdapOutputStream extends OutputStream { - - @Override - public void write(int b) throws IOException { - System.out.println("output stream writing"); - } - - @Override - public void flush() throws IOException { - System.out.println(BAD_FLUSH); - throw new IOException(BAD_FLUSH); - } - } - private static class CustomSocket extends Socket { private int closeMethodCalled = 0; - private LdapOutputStream output = new LdapOutputStream(); - private LdapInputStream input = new LdapInputStream(); - - public void connect(SocketAddress address, int timeout) { - } - - public InputStream getInputStream() { - return input; - } - - public OutputStream getOutputStream() { - return output; - } public int closeMethodCalledCount() { return closeMethodCalled;