Hello Vishva,

The java.net.Authenticator.setDefault() does change the system level state and it can indeed cause issues when multiple applications run within the same java process or different libraries set their own Authenticator in the same application.

In the example you provide:

Authenticator.setDefault(new ProductAuthenticator());
...
try (Connection conn = DriverManager.getConnection(url)) {
    // Connection might fail if credentials aren't real, but the
    // Authenticator.setDefault() call happens during driver initialization.
}
catch (SQLException e) {
    System.out.println("Note: Connection failed (expected), checking Authenticator state...");
}
...

from what you say, the driver implementation is changing the Authenticator to an instance of its choice and thus it's no longer the ProductAuthenticator that you set previously.

I think introducing a change in the JDK implementation of java.net.Authenticator.setDefault() to run arbitrary application code isn't the way to solve this. Especially not when the change is motivated due to:

> The solution might be asking the jar author to fix the faulty code. but it is a production critical case and needs to be fixed soon but also don't want to remove the jar.

As others have noted, the right way to address this is to check with the library author if there are ways to get past this or whether they are willing to address it in the library. Was there a discussion with the library authors about this issue?

If the change to the library code isn't possible, and if your application code is as centralized/isolated as above (unless of course it was meant just as an illustration), then you could consider resetting the Authenticator back to your own in a finally block of that try:

Authenticator.setDefault(new ProductAuthenticator());
...
try (Connection conn = DriverManager.getConnection(url)) {
    // Connection might fail if credentials aren't real, but the
    // Authenticator.setDefault() call happens during driver initialization.
}
catch (SQLException e) {
    System.out.println("Note: Connection failed (expected), checking Authenticator state...");
} finally {
    Authenticator.setDefault(new ProductAuthenticator()); // set the Authenticator back to the desired one
}

If that isn't possible and you still want to intercept the call to Authenticator.setDefault(), and since you seem to have control over how you launch the java process, then you could consider writing a java agent which introduces additional checks in the method. A code example of such an agent is available here https://openjdk.org/jeps/486#Appendix. The example there is written to intercept and reimplement System.exit() calls, but you can do a similar thing for this Authenticator.setDefault() method.

-Jaikiran

On 12/03/26 4:07 pm, Vishva N wrote:
Hi Everyone,
I am facing an issue where the default authenticator set by the Java project owner is getting overridden by third party jars used.
https://bugs.java/bugdatabase/JDK-8379776

The solution might be asking the jar author to fix the faulty code. but it is a production critical case and needs to be fixed soon but also don't want to remove the jar.

So I came up with an idea to provide access control for Autheticator modification to the Java Project owner. Java owner can either throw error or just skip the setDefault call according to the Authenticator class provided.

*PR for the Proposed solution*: https://github.com/openjdk/jdk/pull/30193

I have attached a program with this mail. Kindly download google big query jdbc jar and place all the jars inside the zip in the classpath.

JDBC Jar: https://storage.googleapis.com/simba-bq-release/jdbc/SimbaJDBCDriverforGoogleBigQuery42_1.6.5.1002.zip

*Example Scenario:*
While using Google Big Query JDBC Jar, If proxy username property is present in the connection url, the default authenticator is reset by a code piece in the jar without any checks for existing authenticator.

Reply via email to