Java21运行时App Engine实例开启APIs后连接Cloud SQL的问题
解决方案:开启app-engine-apis的Java 21 App Engine实例连接Cloud SQL
以下是针对你的问题的分步解决方法:
1. 统一JDBC驱动类,修复配置错误
你的代码中生产环境使用了旧的com.mysql.jdbc.Driver,但依赖的mysql-connector-j是8.3.0(属于MySQL 8.x驱动),两者不兼容。所有环境都应该使用com.mysql.cj.jdbc.Driver:
修改WebAppStartStop.java中的生产环境配置:
else if (projectId.equals("xxx")) {//set live credentials persistenceMap.put("jakarta.persistence.jdbc.url", "jdbc:mysql://google/xxxlivedb?cloudSqlInstance=xxx:us-central1:xxxdblive&socketFactory=com.google.cloud.sql.mysql.SocketFactory&useSSL=false"); persistenceMap.put("jakarta.persistence.jdbc.user", "xxxliveuser"); persistenceMap.put("jakarta.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver"); // 替换旧的驱动类名 }
2. 升级App Engine Maven插件到兼容Java 21的版本
你当前使用的appengine-maven-plugin版本是2.2.0,不支持Java 21。升级到最新稳定版本:
修改pom.xml中的插件配置:
<plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>appengine-maven-plugin</artifactId> <version>2.6.0</version> <!-- 支持Java 21的版本 --> <configuration> <promote>false</promote> <projectId>XXXXX</projectId> <version>9</version> </configuration> </plugin>
同时升级Maven编译器插件到支持Java 21的版本:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.12.1</version> <!-- 支持Java 21的版本 --> <configuration> <source>21</source> <target>21</target> <compilerArguments> <endorseddirs>${endorsed.dir}</endorseddirs> </compilerArguments> </configuration> </plugin>
3. 调整类加载配置,避免App Engine旧API层的冲突
开启app-engine-apis时,App Engine的系统类加载器会优先加载部分旧类,可能和你的MySQL驱动、Socket Factory冲突。在appengine-web.xml中添加类加载配置,让应用优先加载自身的JAR包:
<?xml version="1.0" encoding="utf-8"?> <appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> <runtime>java21</runtime> <app-engine-apis>true</app-engine-apis> <sessions-enabled>true</sessions-enabled> <class-loader-config> <priority-specifier> <name>com.google.cloud.sql</name> <!-- 优先加载Cloud SQL Socket Factory类 --> <priority>HIGH</priority> </priority-specifier> <priority-specifier> <name>com.mysql.cj</name> <!-- 优先加载MySQL驱动类 --> <priority>HIGH</priority> </priority-specifier> </class-loader-config> <staging> <enable-jar-classes>true</enable-jar-classes> </staging> <instance-class>F2</instance-class> </appengine-web-app>
4. 确认Cloud SQL Socket Factory依赖的兼容性
确保mysql-socket-factory-connector-j-8的版本和mysql-connector-j版本兼容,升级到最新稳定版本:
修改pom.xml中的依赖:
<dependency> <groupId>com.google.cloud.sql</groupId> <artifactId>mysql-socket-factory-connector-j-8</artifactId> <version>1.18.1</version> </dependency>
5. 改用Jakarta EE数据源配置(可选,更规范)
手动创建EntityManagerFactory可能会避开App Engine的数据源管理,改用persistence.xml结合动态属性覆盖的方式,让容器管理数据源,减少类加载冲突:
在persistence.xml中配置通用属性:
<persistence-unit name="com.xxx_xxx_war_1.0PU" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <properties> <property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/> <!-- 其他通用JPA配置 --> </properties> </persistence-unit>
保持WebAppStartStop.java中动态覆盖环境相关的URL、用户名属性即可。
验证步骤
- 清理Maven缓存并重新构建:
mvn clean install - 本地测试(使用App Engine模拟器),确认开启
app-engine-apis时能正常连接数据库 - 部署到App Engine标准环境,查看应用日志确认连接成功
内容的提问来源于stack exchange,提问作者Henschel lungu
相关产品推荐
相关产品推荐

