GoogleCloudPlatform / java-docs-samples

Java and Kotlin Code samples used on cloud.google.com
https://cloud.google.com/java
Apache License 2.0
1.75k stars 2.82k forks source link

Can't connect to MySQL from App Engine after upgrading to MySQL 8.0 #9418

Closed jsalidoforms closed 1 month ago

jsalidoforms commented 1 month ago

We opened a ticket with Google support (# 52128844) but they advised us to report our issue here.

We have a MySQL instance that we could connect to from App Engine Standard running Java 8 when it was running MySQL 5.6. The instance and App Engine are in the same project. The instance uses a public IP address.

appengine-web.xml:

<use-google-connector-j>true</use-google-connector-j>
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>libraries-bom</artifactId>
    <version>15.0.0</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>
<dependency>
    <groupId>com.google.appengine</groupId>
    <artifactId>appengine-api-1.0-sdk</artifactId>
    <version>2.0.24</version>
</dependency>
Class.forName("com.mysql.jdbc.GoogleDriver");
Connection conn = DriverManager.getConnection("jdbc:google:mysql://myproject:myregion:myinstance/mydatabase?user=myuser&password=mypassword");

We upgraded the instance in place to MySQL 8.0.

We confirmed the instance is running by connecting with MySQL Workbench.

Based on the examples here: https://cloud.google.com/sql/docs/mysql/connect-app-engine-standard And here: https://github.com/GoogleCloudPlatform/java-docs-samples/blob/main/cloud-sql/mysql/servlet/src/main/java/com/example/cloudsql/ConnectorConnectionPoolFactory.java

We added dependencies:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>
<dependency>
    <groupId>com.google.cloud.sql</groupId>
    <artifactId>mysql-socket-factory-connector-j-8</artifactId>
    <version>1.18.1</version>
</dependency>
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>4.0.3</version>
</dependency>

And changed our code to:

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql:///mydatabase");
config.setUsername("myuser");
config.setPassword("mypassword");
// Without this line throws RuntimeException Failed to get driver instance for jdbcUrl=...
config.setDriverClassName("com.mysql.cj.jdbc.Driver");
config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory");
config.addDataSourceProperty("cloudSqlInstance", "myproject:myregion:myinstance");
// Including or excluding this line makes no difference in the error
config.addDataSourceProperty("unixSocketPath", "/cloudsql/myproject:myregion:myinstance");
// Including or excluding this line makes no difference in the error
config.addDataSourceProperty("ipTypes", "PUBLIC");
HikariDataSource source = new HikariDataSource(config);     
Connection conn = source.getConnection();

The line

HikariDataSource source = new HikariDataSource(config); 

Throws this exception:

com.zaxxer.hikari.pool.HikariPool$PoolInitializationException: Failed to initialize pool: Could not create connection to database server.
com.zaxxer.hikari.pool.HikariPool.throwPoolInitializationException(HikariPool.java:596)
com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:582)
com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:115)
com.zaxxer.hikari.HikariDataSource.(HikariDataSource.java:81)
jsalidoforms commented 1 month ago

This is caused by having urlfetch enabled in the application. https://github.com/googleapis/google-auth-library-java/issues/191