Search code examples
pythonjdbcjksjaydebeapi

Provide certificates to Python jaydebeapi lib for jdbc MYSQL connection adapter


There's a JDBC server that I need to connect through python to.

Using jaydebeapi lib, I'm able to spin up a connection non-ssl but when connecting to a staging database which enforces certs, I don't understand how to provide the jks file it needs to connect to the mysql through jdbc.

Dependencies:

python==3.9.16
JayDeBeApi==1.2.3
JPype1==1.4.1

Code:

import jpype
import jaydebeapi

MYSQL_VJDBC_HOST = ""
MYSQL_VJDBC_JAR_PATH = ""
MYSQL_VJDBC_CERT_PATH = ""
MYSQL_VJDBC_CERT_PW = ""
MYSQL_VJDBC_SECRET = ""


def get_jdbc_connection(self):
    url = f"jdbc:vjdbc:servlet:{MYSQL_VJDBC_HOST}"
    jvm_path = jpype.getDefaultJVMPath()
    jpype.startJVM(
        jvm_path,
        f"-Djava.class.path={MYSQL_VJDBC_JAR_PATH}",
        f"-Djavax.net.ssl.trustStore={MYSQL_VJDBC_CERT_PATH}",
        f"-Djavax.net.ssl.trustStorePassword={MYSQL_VJDBC_CERT_PW}",
    )
    try:
        return jaydebeapi.connect(
            "de.simplicit.vjdbc.VirtualDriver",
            url,
            {
                "user": "mysql",
                "password": MYSQL_VJDBC_SECRET,
                "secure": "true",
                # "cert_file": sMYSQL_VJDBC_CERT_PATH,
                # "cert": MYSQL_VJDBC_CERT_PATH,
            },
            MYSQL_VJDBC_JAR_PATH,
        )
    except Exception as exception:
        print(f"There was an error connecting\n:{exception}")
        raise exception

Error:

  File "*/src/mysql_adapter.py", line 29, in get_jdbc_connection
return jaydebeapi.connect(
  File "*/.venv/lib/python3.9/site-packages/jaydebeapi/__init__.py", line 412, in connect
jconn = _jdbc_connect(jclassname, url, driver_args, jars, libs)
  File "*/.venv/lib/python3.9/site-packages/jaydebeapi/__init__.py", line 230, in _jdbc_connect_jpype
return jpype.java.sql.DriverManager.getConnection(url, *dargs)
  java.sql.java.sql.SQLException: java.sql.SQLException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Solution

  • In jaydebeapi lib, driver arguments are passed through.

    In VJDBC "truststore" was the missing argument which is a string path.

    Required a bit of digging but hopefully this is helpful to users not familiar with Java.

    jaydebeapi.connect(
            "de.simplicit.vjdbc.VirtualDriver",
            url,
            {
                "user": "mysql",
                "password": MYSQL_VJDBC_SECRET,
                "secure": "true",
                "truststore": MYSQL_VJDBC_CERT_PATH,
            },
            MYSQL_VJDBC_JAR_PATH,
        )