On Tue, 10 Feb 2026 07:18:29 GMT, Jaikiran Pai <[email protected]> wrote:

>> Can I please get a review of this change which proposes to fix the issue 
>> reported in https://bugs.openjdk.org/browse/JDK-8362268?
>> 
>> The underlying issue here is simple - A `javax.naming.Context` for LDAP is 
>> backed by a JDK internal `com.sun.jndi.ldap.LdapCtx` instance. Each 
>> `LdapCtx` uses a `com.sun.jndi.ldap.LdapClient` instance to do the LDAP 
>> operations. Each `LdapClient` further uses a `com.sun.jndi.ldap.Connection` 
>> instance. Each `Connection` instance uses a `Socket` and the socket's 
>> `InputStream` and `OutputStream` to read/write LDAP messages from/to a LDAP 
>> server. Each `Connection` instance spawns a `Thread` to read (over the 
>> InputStream) and queue incoming messages from the LDAP server.
>> 
>> When a LDAP backed `javax.naming.Context` initiates an operation, for 
>> example a `Context.lookup()`, then internally the LdapCtx initiates a LDAP 
>> request over the Connection's `OutputStream` and then waits for a LDAP 
>> response to arrive. In the issue reported here, it so happens that while 
>> reading over the `Connection`'s `InputStream`, the `InputStream.read()` 
>> raises an `IOException` (for whatever reason). That `IOException` rightly 
>> initiates the close of the `Connection` instance. Closing a `Connection` 
>> instance involves queuing a marker response for all waiting thread(s) to 
>> notice and raise an IOException, which they can ulimately propagate as a 
>> `NamingException` to the application. Additionally, the closing of the 
>> `Connection` also closes the `InputStream` and `OutputStream` of that 
>> `Connection`.
>> 
>> When a thread that was waiting for a LDAP response, in LdapCtx, wakes up due 
>> to an IOException, it attempts to send a "abandon request" LDAP message over 
>> the `Connection`, so that the server knows that the client has abandoned the 
>> request. Since the Connection and its Input/OutputStream(s) are already 
>> closed, trying to write a message over the OutputStream can/will lead to an 
>> exception. The implementation of `Connection.abandonRequest(LdapRequest ldr, 
>> Control[] reqCtls)` which is where this code resides, guards against such 
>> exceptions by catching and ignoring an `IOException` from an 
>> `OutputStream.write(...)/flush()` call.
>> 
>> Although `OutputStream.write(...)` is specified to throw an IOException if 
>> that stream is already closed, not all implementations adhere to that 
>> specification. For example, `java.io.BufferedOutputStream` does not throw 
>> any exception when `write(...)` is invoked on a closed `OutputStream`. 
>> Incidentally, the `Connection` instance's `Outp...
>
> Jaikiran Pai has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   add comment

Thank you Weibing for running your test and thank you Daniel and Michael for 
the inputs. I've updated this PR to not rely on `useable` field and instead 
rely on the `com.sun.jndi.ldap.LdapRequest` itself to decide whether or not to 
send an "abandon request" message over the connection. The `LdapRequest` has 
the necessary detail whether a connection is closed or not and if the 
connection is closed then we skip the BER message creation and sending of that 
message over the stream.

> The BER stream is dumped to tracefile although not request is being sent, 
> that is wrong.

As a separate activity, I will check other places where this might be 
happening. With the current proposed update to the PR, this no longer happens 
for the abandon request.

With the changes in this PR, tier1, tier2 and tier3 tests passed and test 
repeat of 50 for `test/jdk/com/sun/jndi/ldap/` too completed without issues.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/29638#issuecomment-3875796425

Reply via email to