Summary
-------
Update the JDK built-in LDAP provider's client implementation to ignore a connect timeout value when a custom LDAP socket factory does not support the creation of unconnected sockets.
Problem
-------
The JDK built-in LDAP provider's client implementation allows to specify a custom socket factory implementation via the `"java.naming.ldap.factory.socket"` LDAP environment property.
Starting from JDK 9, such implementations are required to implement the `"javax.net.SocketFactory"` abstract class.
However, if a connect timeout is specified via the `"com.sun.jndi.ldap.connect.timeout"` environment property and the provided custom socket factory implementation does not implement the `"public Socket createSocket()"` method for creating unconnected sockets, the `"java.io.IOException"` is thrown by this method default implementation, and the LDAP connection attempt fails.
Such behavior contradicts the expectations set up by the following internal documentation in the JNDI/LDAP provider source code:
"If a timeout is supplied but unconnected sockets are not supported
then the timeout is ignored and a connected socket is created"
Solution
--------
Change the JNDI/LDAP provider client's internal implementation to ignore the timeout value if the provided custom socket factory implementation doesn't support the creation of unconnected sockets.
Document the following LDAP environment property that can be used to set a custom socket factory implementation:
java.naming.ldap.factory.socket
Amend documentation of the following connect timeout LDAP environment property to set the expectations related to the custom socket factory implementations:
com.sun.jndi.ldap.connect.timeout
Specification
-------------
diff --git a/src/java.naming/share/classes/module-info.java b/src/java.naming/share/classes/module-info.java
index c4c7a606c6c..11360e88676 100644
--- a/src/java.naming/share/classes/module-info.java
+++ b/src/java.naming/share/classes/module-info.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,21 +36,31 @@
* The following implementation specific environment properties are supported by the
* default LDAP Naming Service Provider implementation in the JDK:
* <ul>
+ * <li>{@code java.naming.ldap.factory.socket}:
+ * <br>The value of this environment property specifies the fully
+ * qualified class name of the socket factory used by the LDAP provider.
+ * This class must implement the javax.net.SocketFactory abstract class
+ * and provide an implementation of the static "getDefault()" method that
+ * returns an instance of the socket factory. By default the environment
+ * property is not set.
+ * </li>
* <li>{@code com.sun.jndi.ldap.connect.timeout}:
- * <br>The value of this property is the string representation
- * of an integer representing the connection timeout in
- * milliseconds. If the LDAP provider cannot establish a
- * connection within that period, it aborts the connection attempt.
+ * <br>The value of this environment property is the string representation
+ * of an integer specifying the connection timeout in milliseconds.
+ * If the LDAP provider cannot establish a connection within that period,
+ * it aborts the connection attempt.
* The integer should be greater than zero. An integer less than
* or equal to zero means to use the network protocol's (i.e., TCP's)
* timeout value.
* <br> If this property is not specified, the default is to wait
* for the connection to be established or until the underlying
* network times out.
+ * <br> If a custom socket factory is provided via environment property
+ * {@code java.naming.ldap.factory.socket} and unconnected sockets
+ * are not supported, the specified timeout is ignored
+ * and the provider behaves as if no connection timeout was set.
* </li>
* <li>{@code com.sun.jndi.ldap.read.timeout}:
* <br>The value of this property is the string representation
- * of an integer representing the read timeout in milliseconds
+ * of an integer specifying the read timeout in milliseconds
* for LDAP operations. If the LDAP provider cannot get a LDAP
* response within that period, it aborts the read attempt. The
* integer should be greater than zero. An integer less than or