aws / aws-advanced-jdbc-wrapper

The Amazon Web Services JDBC Driver has been redesigned as an advanced JDBC wrapper. This wrapper is complementary to and extends the functionality of an existing JDBC driver to help an application take advantage of the features of clustered databases such as Amazon Aurora.
Apache License 2.0
208 stars 41 forks source link

java.sql.DriverManager.getConnection fails with "No suitable driver found" #1048

Closed zaza closed 2 months ago

zaza commented 3 months ago

Describe the bug

A connection to an Aurora/Postgres database cannot be established because calling java.sql.DriverManager.getConnection fails with java.sql.SQLException: No suitable driver found for jdbc:aws-wrapper:postgresql://...

This appears to be an intermittent error, but so far we haven't been able to mitigate it except by restarting the app.

Both drivers are on the classpath.

Expected Behavior

The connection is established reliably, each time.

What plugins are used? What other connection properties were set?

None

Current Behavior

Caused by: java.sql.SQLException: No suitable driver found for jdbc:aws-wrapper:postgresql://(...)/production
    at java.sql.DriverManager.getConnection(DriverManager.java:706) ~[java.sql:?]
    at java.sql.DriverManager.getConnection(DriverManager.java:190) ~[java.sql:?]

Reproduction Steps

There are no reliable reproduction steps as the error appears to be intermittent, yet highly impactful.

Possible Solution

As suggested here and here ensure the Postgres driver is registered before establishing a connection.

Additional Information/Context

The exact same issue has been brought up multiple times already with no clear solution:

The AWS Advanced JDBC Driver version used

2.3.6

JDK version used

openjdk 1.8.0_412

Operating System and version

Amazon Linux 2023.4.20240513

ucjonathan commented 3 months ago

It would be interesting to enumerate the drivers that DriverManager is able to find since this is a somewhat "automagical" process. Here is some code to try out. Might be a problem with the class loader in the particular application server that you're running.

import java.sql.Driver;
import java.sql.DriverManager;
import java.util.Enumeration;

public class ListJDBCDrivers {
    public static void main(String[] args) {
        Enumeration<Driver> drivers = DriverManager.getDrivers();

        if (!drivers.hasMoreElements()) {
            System.out.println("No JDBC drivers found in the classpath.");
        } else {
            System.out.println("Available JDBC drivers:");
            int count = 1;
            while (drivers.hasMoreElements()) {
                Driver driver = drivers.nextElement();
                System.out.println(count + ". " + driver.getClass().getName());
                count++;
            }
        }
    }
}
karenc-bq commented 2 months ago

Hi @zaza, since v2.3.1 the wrapper is able to automatically register the target driver (PGJDBC in this case) if it is not registered on the classpath. The wrapper would throw a different, more specific error if the PGJDBC driver is missing:

Caused by: java.lang.ClassNotFoundException: org.postgresql.ds.PGSimpleDataSource

The exception posted suggests the wrapper is not present in the classpath. Could you please try @ucjonathan's suggestion to verify if the wrapper is registered on the classpath when the error is thrown?

zaza commented 2 months ago

We have updated the wrapper to 2.3.7 and implemented something similar, but so far the error has not occurred.

hsuamz commented 2 months ago

Will be closing this issue since a resolution has been found. Please feel free to re-open this issue if it still persists or if you have any related questions.

Thank you!