aws-mysql-jdbc icon indicating copy to clipboard operation
aws-mysql-jdbc copied to clipboard

aws-mysql-jdbc should be tollerant to JDBC URL params without value like disableMariaDbDriver

Open kerny3d opened this issue 2 years ago • 1 comments

Describe the feature

Considering the issue:

  • https://jira.mariadb.org/browse/CONJ-423

I would ask you if aws-mysql-jdbc driver could be tollerant to JDBC url parameter like disableMariaDbDriver. MySQL driver is actually tollerant to this type of parameters.

Use Case

I'm porting a legacy app running on Tomcat 9 to EKS and RDS Aurora. This app have both mysql-connector-java-8.0.25.jar and mariadb-java-client-2.7.2.jar in its classpath: both the drivers are needed because our app could connect to multiple DBMS at the same time.

The version of MariaDB driver we use supports the parameter disableMariaDbDriver used like:

jdbc:mysql://localhost:3306/mydb?disableMariaDbDriver

This let the MariaDB driver to ignore this kind of URL, delegating the connection to the MySQL driver.

During the porting we replaced our MySQL driver with aws-mysql-jdbc and we fixed the JDBC URL like:

jdbc:mysql:aws://myrds:3306/mydb?disableMariaDbDriver

But this generate the following stack trace during connect opening:

java.lang.NullPointerException: null
        at java.util.Hashtable.put(Hashtable.java:460) ~[?:1.8.0_265]
        at java.util.Hashtable.putAll(Hashtable.java:524) ~[?:1.8.0_265]
        at software.aws.rds.jdbc.mysql.shading.com.mysql.cj.conf.ConnectionUrl.getConnectionArgumentsAsProperties(ConnectionUrl.java:780) ~[aws-mysql-jdbc-1.1.0.jar:?]
        at software.aws.rds.jdbc.mysql.shading.com.mysql.cj.jdbc.ha.ConnectionProxy.autodetectClusterAndCreateProxyInstance(ConnectionProxy.java:122) ~[aws-mysql-jdbc-1.1.0.jar:?]
        at software.aws.rds.jdbc.mysql.shading.com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:221) ~[aws-mysql-jdbc-1.1.0.jar:?]
        at org.apache.tomcat.dbcp.dbcp2.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:52) ~[tomcat-dbcp.jar:9.0.60]    
        at org.apache.tomcat.dbcp.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:415) ~[tomcat-dbcp.jar:9.0.60]     
        at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.java:111) ~[tomcat-dbcp.jar:9.0.60]
        at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:649) ~[tomcat-dbcp.jar:9.0.60]    
        at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:532) ~[tomcat-dbcp.jar:9.0.60]
        at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.lambda$getConnection$0(BasicDataSource.java:720) ~[tomcat-dbcp.jar:9.0.60]
        at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_265]
        at org.apache.tomcat.dbcp.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:722) ~[tomcat-dbcp.jar:9.0.60]

While the MySQL driver is tollerant to unknown, valueless parameters (at least the version we use).

Proposed Solution

To replicate in some way the params management of the official MySQL driver.

Other Information

A simple workaround for this is to add a dummy value to this parameter like:

jdbc:mysql:aws://myrds:3306/mydb?disableMariaDbDriver=whatever

To replicate the case you can create an empty dir, put in the aws-mysql-jdbc-1.1.0.jar and a Main.java with the following content:

import java.sql.Connection;      
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;   
import java.sql.SQLException;    

public class Main {

        private static final String CONNECTION_STRING = "jdbc:mysql:aws://myrds:3306?mydb";    
        private static final String USER = "admin";
        private static final String PASSWORD = "very-long-password";

        public static void main(String[] args) throws SQLException {

                try (final Connection conn = DriverManager.getConnection(CONNECTION_STRING, USER, PASSWORD)) {
                        DatabaseMetaData metaData = conn.getMetaData();

                        String url = metaData.getURL();

                        System.out.println(url);
                }
        }

}

Acknowledgements

  • [ ] I may be able to implement this feature request
  • [ ] This feature might incur a breaking change

The AWS JDBC Driver for MySQL version used

1.1.0

JDK version used

openjdk version "1.8.0_265" OpenJDK Runtime Environment (build 1.8.0_265-b01) OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)

Operating System and version

Debian 10.6 from openjdk:8 Docker image

kerny3d avatar Aug 25 '22 09:08 kerny3d

Hello @kerny3d

Thank you for raising the issue. We understand this issue is causing inconveniences in your workflows. We'll be investigating this issue and will update you when we have a release. We appreciate your patience.

sergiyvamz avatar Aug 25 '22 17:08 sergiyvamz

Hello @kerny3d

The fix has been merged, can you please test out our 1.1.2-Snapshot build here and let us know if the issue persists.

Thank you!

sergiyvamz avatar Oct 19 '22 21:10 sergiyvamz

I confirm the fix.

Thank you.

kerny3d avatar Oct 24 '22 14:10 kerny3d

Hi @bobfields

Thanks for reaching out.

It looks like there is an extra ":" in the protocol section of the connection URL that may be causing the issue.

Please let us know if this resolves the issue.

Thank you

aaronchung-bitquill avatar Feb 28 '23 20:02 aaronchung-bitquill

Yeah I noticed the extra :: and removed the comment. But now we are seeing a certificate path exception, which we did not see with the mariadb driver. Seems to be fixed by the information from https://stackoverflow.com/questions/48286407/ssl-exception-on-java-path-does-not-chain-with-any-of-the-trust-anchors - importing the entire certificate chain (from AWS aurora) into the JVM. Odd that the 2 drivers should work differently for SSL connections.

bobfields avatar Mar 01 '23 21:03 bobfields