我有一个 java ee 8 应用程序,我已将其迁移到 jakarta 10 应用程序。我使用谷歌应用程序引擎标准服务器。我最近将其迁移到 java 17 运行时,它正在连接到云 sql 数据库,一切运行良好。这是我的 pom.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.figjaminc</groupId>
<artifactId>XXXXX</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>XXXX</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>libraries-bom</artifactId>
<version>26.30.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.json</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.16.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.1</version>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>2.0.12</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.sendgrid</groupId>
<artifactId>java-http-client</artifactId>
<version>4.3.6</version>
<type>jar</type>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.platform/jakarta.jakartaee-api -->
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>10.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>3.1.5</version> <!-- Use the latest version available -->
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>3.1.5</version> <!-- Use the latest version available -->
</dependency>
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.3.0</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-core</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sendgrid/sendgrid-java -->
<dependency>
<groupId>com.sendgrid</groupId>
<artifactId>sendgrid-java</artifactId>
<version>4.7.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-storage</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-tasks</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-csv -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.cloud.sql/mysql-socket-factory-connector-j-8 -->
<dependency>
<groupId>com.google.cloud.sql</groupId>
<artifactId>mysql-socket-factory-connector-j-8</artifactId>
<version>1.17.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api -->
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.2.0</version>
<configuration>
<promote>false</promote>
<projectId>XXXXX</projectId>
<version>9</version>
<!--
<projectId>XXXXX</projectId>
<version>9</version>
-->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
这就是我设置 appengine-web.xml 的方式
<?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>
<staging>
<enable-jar-classes>true</enable-jar-classes>
</staging>
<instance-class>F2</instance-class>
当我的应用程序启动时,我可以创建一个entityManagerFactory
package com.figjaminc.startup;
import com.google.cloud.ServiceOptions;
import jakarta.persistence.Persistence;
import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
public class WebAppStartStop implements ServletContextListener {
private static final String class_name = "WebAppStartStop";
private static final Logger LOGGER = Logger.getLogger(WebAppStartStop.class.getName());
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
String startupReport = "";
startupReport += initializeEntityManager();
LOGGER.info("WebAppStartStop startup_report:" + startupReport);
}
private String initializeEntityManager() {
String projectId = ServiceOptions.getDefaultProjectId();
Map<String, String> persistenceMap = new HashMap<String, String>();
//set sandbox credentials
if (projectId.equals("xxx-sandbox")) {
persistenceMap.put("jakarta.persistence.jdbc.url", "jdbc:mysql://google/xxxdb?cloudSqlInstance=xxx:us-central1:xxxdb3&socketFactory=com.google.cloud.sql.mysql.SocketFactory&useSSL=false");
persistenceMap.put("jakarta.persistence.jdbc.user", "xxxuser");
persistenceMap.put("jakarta.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
}//if
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");//changed for new demo
persistenceMap.put("jakarta.persistence.jdbc.user", "xxxliveuser");
persistenceMap.put("jakarta.persistence.jdbc.driver", "com.mysql.jdbc.Driver");
}//else
else {
persistenceMap.put("jakarta.persistence.jdbc.url", "jdbc:mysql://localhost:3306/xxxdb?zeroDateTimeBehavior=CONVERT_TO_NULL");
persistenceMap.put("jakarta.persistence.jdbc.user", System.getenv("db_username"));
persistenceMap.put("jakarta.persistence.jdbc.password", System.getenv("db_password"));
persistenceMap.put("jakarta.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
}//else
CommonDbMethods.factory = Persistence.createEntityManagerFactory("com.xxx_xxx_war_1.0PU", persistenceMap);
return "Entity Manager initialized";
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
LOGGER.info("Shutting Down");
}
}
安全限制阻止使用 Java 21 的 App Engine 连接到 Cloud SQL。
有两种可能的解决方案:
Cloud SQL Proxy with Public IP:根据官方指南设置Cloud SQL Proxy,并在您的应用程序中配置环境变量。
无服务器 VPC 访问:如果您的 Cloud SQL 实例有私有 IP,请按照文档使用无服务器 VPC 访问来设置 VPC 连接器。
注意:验证代码中的 Cloud SQL 连接详细信息。
您还可以查看此说明(从App Engine标准环境连接)确保遵循最佳实践。
更新:
确保
app-engine-apis
中的 true
设置为 appengine-web.xml
。
验证您的 Cloud SQL 实例是否具有公共 IP(可能是默认 IP)。
仔细检查代码中的连接详细信息(URL、用户名、密码)。
将
mysql-socket-factory-connector-j-8
依赖项保留在 pom.xml
中。
如果连接失败,请检查 App Engine 日志并尝试暂时禁用
app-engine-apis
以隔离冲突。
虽然具有公共 IP Cloud SQL 的 App Engine 标准可能并不绝对需要 Cloud SQL 代理,但这些文档可以让您更好地了解连接选项和各种场景下需要考虑的因素。