在 2024 年 1 月失去 Java 8 支持之前,我终于将长期运行的 Google App Engine Java 8 项目迁移到 Java 11+ 标准环境。
但我需要使用旧的捆绑服务,包括数据存储、Blobstore 和任务队列。我应该通过“安装 App Engine API Jar”来完成此操作。
我遵循了以下 Google 教程https://cloud.google.com/appengine/docs/standard/java-gen2/services/access
特别是,我需要通过将以下内容添加到 app-engine.web.xml 文件来“安装 App Engine API JAR”:
但是尝试通过 Android Studio 中的 Gradle 插件构建/部署项目会出现异常“无法识别的元素
很遗憾 - 我无法在保留旧的捆绑遗留功能的同时部署到新的 Java 11 服务器环境。
注意:因为我使用 Android Studio 中的 Gradle 插件来构建和部署服务器,所以我没有 Maven 使用的 pom.xml 文件。
任何有关如何使用 app-engine.web.xml 中嵌入的必要“
Android Studio Giraffe 2022.3.1 补丁 4 与 Gradle 7.4.2
使用 Objectify 5 在 GAE 标准环境上运行服务器
AppEngine Gradle 文件
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'com.google.cloud.tools.appengine'
apply plugin: 'com.google.cloud.tools.endpoints-framework-server'
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.google.cloud.tools:endpoints-framework-gradle-plugin:2.1.0'
classpath 'com.google.cloud.tools:appengine-gradle-plugin:2.4.2'
}
}
repositories {
google()
mavenCentral()
}
appengine {
deploy {
version = "GCLOUD_CONFIG"
projectId = "GCLOUD_CONFIG"
}
}
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
dependencies {
implementation (group: 'com.google.appengine', name: 'appengine-api-1.0-sdk', version: '2.0.0')
implementation 'com.google.endpoints:endpoints-framework:2.2.2'
implementation ('com.google.http-client:google-http-client-gson:1.40.1') {
exclude (group: 'httpclient', module: 'httpclient')
}
implementation 'javax.inject:javax.inject:1'
implementation 'javax.servlet:servlet-api:3.0-alpha-1'
implementation 'javax.activation:javax.activation-api:1.2.0'
implementation ('com.google.firebase:firebase-admin:8.1.0') {
exclude (group: 'com.google.guava')
}
implementation 'com.google.guava:guava:31.0.1-jre'
implementation (group: 'com.google.appengine.tools', name: 'appengine-gcs-client', version: '0.8.2')
implementation 'com.googlecode.objectify:objectify:5.1.25'
implementation "com.stripe:stripe-java:20.90.0"
}
应用程序引擎.web.xml
<?xml version="1.0" encoding="utf-8"?\>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0"\>
<application\>my-fashion-project\</application\>
<version\>1\</version\>
<runtime\>java11\</runtime\>
<app-engine-apis\>true\</app-engine-apis\> // THIS IS THE LINE THAT CAUSES EXCEPTION
<threadsafe\>true\</threadsafe\>
<url-stream-handler\>urlfetch\</url-stream-handler\>
<system-properties\>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties" /\>
</system-properties\>
<sessions-enabled\>
true
</sessions-enabled\>
<resource-files\>
<include path="/\*\*.json" /\>
</resource-files\>
<automatic-scaling\>
<min-instances\>1\</min-instances\>
</automatic-scaling\>
</appengine-web-app\>
web.xml
<?xml version="1.0" encoding="utf-8"?\><web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5"\>
<app-engine-apis\>true\</app-engine-apis\>
<filter\>
<filter-name\>ObjectifyFilter\</filter-name\>
<filter-class\>com.googlecode.objectify.ObjectifyFilter\</filter-class\>
</filter\>
<filter-mapping\>
<filter-name\>ObjectifyFilter\</filter-name\>
<url-pattern\>/\*\</url-pattern\>
</filter-mapping\>
<servlet\>
<servlet-name\>EndpointsServlet\</servlet-name\>
<servlet-class\>com.google.api.server.spi.EndpointsServlet\</servlet-class\>
<init-param\>
<param-name\>services\</param-name\>
<param-value\>
com.myfashionserver.entities.MemberEndpoint,
............ (list of entity endpoints excluded) ............
</param-value\>
</init-param\>
</servlet\>
<servlet-mapping\>
............ (list of servlets excluded) ............
<security-constraint\>
<web-resource-collection\>
<web-resource-name\>queue\</web-resource-name\>
<url-pattern\>/queue/\*\</url-pattern\>
</web-resource-collection\>
<auth-constraint\>
<role-name\>admin\</role-name\>
</auth-constraint\>
</security-constraint\>
<welcome-file-list\>
<welcome-file\>blog.html\</welcome-file\>
</welcome-file-list\>
</web-app\>
Android Studio Gradle 构建异常日志
com.google.apphosting.utils.config.AppEngineConfigException: Unrecognized element \<app-engine-apis\>
因此,我将发布此问题的答案,以防其他人也尝试将其 GAE 项目更新到 Java 11+ 并尝试使用旧版捆绑服务,并在使用时遇到无法构建其 App Engine 标准项目的情况
<app-engine-apis>true</app-engine-apis>
在 appengine-web.xml 文件中。
问题是我的 GAE 服务器项目使用了原始的 Cloud Endpoints Framework,该框架可以方便地为服务器和 Android 设备客户端创建服务器 API 存根(请参阅 https://cloud.google.com/endpoints/docs/frameworks/about-cloud -端点框架)。
但是 Cloud Endpoints Framework 使用 Java 8 环境。该项目在 Github 上已“死亡”,并已被使用 OpenAPI 协议的较新 Google 端点放弃。
所以问题实际上出在 web.xml 文件中,我在其中指定了 Endpoints servlet 类来构建 Endpoints servlet:
<servlet-class>com.google.api.server.spi.EndpointsServlet</servlet-class>
旧的 Cloud Endpoints Framework 需要此 servlet 规范以及 build.gradle 依赖项:
implementation 'com.google.endpoints:endpoints-framework:2.2.2'
使用此框架可以防止 appengine-web.xml 中的
<app-engine-apis>true</app-engine-apis>
规范。该项目将无法构建。
我的解决方案:我无法使用旧版捆绑服务,而是被迫更新 GAE 服务器以使用新的 Google Cloud 客户端库以及 Firebase 中的 Cloud Storage 和 Datastore。服务器数据库已经在 Firebase Datastore 环境下。
但是,没有明确说明的是,如果您想将 Objectify 与较新的云客户端库一起使用,则必须将 Objectify 版本更新到 6。任何低于 6 的 Objectify 版本都无法与云客户端库一起使用。
我相信这从长远来看是有好处的,因为谷歌最终将放弃遗留的捆绑服务,并且基于旧的API构建整个数据库是愚蠢的。我现在仍在使用 Cloud Endpoints 框架在 Java 17 环境中构建和部署项目。最终,我将不得不使用 openAPI 实现新的云端点,但这将需要对 Android、iPhone 和网页客户端代码进行彻底改造 - 这是一项非常艰巨的任务,将“杀死”任何旧版本的客户端应用程序。
希望这可以帮助任何处于同样困境的人。