Java 8 已达到支持终止期限,并将于 2026 年 1 月 31 日
弃用。弃用后,您将无法部署 Java 8 应用,即使您的组织之前曾使用组织政策重新启用旧版运行时的部署,也无法部署。现有的 Java 8 应用在
弃用日期之后将继续运行并接收流量。我们建议您
迁移到最新支持的 Java 版本。
从 Java 7 运行时迁移到 Java 8 运行时
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
本页面介绍了如何将现有 App Engine 应用从 Java 7 运行时迁移到 Java 8 运行时。请注意,App Engine Java 运行时基于 OpenJDK。
为您的应用指定 Java 8 运行时
要在 Java 8 运行时中运行您的应用,请执行以下操作:
将 <runtime>java8</runtime>
添加到 appengine-web.xml
文件中:
重新部署您的应用。
从不受支持的服务迁移
Java 8 运行时不支持在 Java 7 运行时中可用的某些已弃用服务。在迁移到 Java 8 之前,Google 建议您先使用推荐的替代方案对应用进行更改,并在 Java 7 运行时中测试完成了这些更改的应用。
以下弃用的服务在 Java 8 运行时中不可用:
弃用的服务 |
推荐的替代方案 |
Cloud Endpoints v1 |
迁移到 v2,产品已重名为 Cloud Endpoints Frameworks。请注意,这可能要求您更改您的 Web、Android 或 iOS 应用。 |
AppStats (appengine-api-labs jar) |
迁移至 Cloud Trace。该 SDK 会对在 Java 8 运行时中使用 com.google.appengine.tools.AppstatsFilter 类的应用生成错误确保删除 web.xml 中所有对 AppstatsFilter 的引用。 |
在 Java 8 上,重新打包的类需要新的导入路径。例如,如果您的应用使用了 com.google.appengine.repackaged.com.google.common.base.Optional
,则需要导入 com.google.appengine.repackaged.com.google.common.base.$Optional
,类名称前添加了 $
前缀。
迁移使用 java.net.HttpURLConnection 的免费应用
如果您的应用未启用结算功能,并使用 java.net.HttpURLConnection
类或借助使用该类的 Google 客户端库 发起 HTTP(S) 请求,则将导致运行时错误。为避免这种情况,请在应用的 appengine-web.xml
中将 <url-stream-handler>
设置为 urlfetch
:
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<!-- ... -->
<url-stream-handler>urlfetch</url-stream-handler>
<!-- ... -->
</appengine-web-app>
另外,您可以为应用启用结算功能,而不是指定 urlfetch
,并使用默认的 native
设置。在 Java 7 上运行应用应该不会造成任何费用增加。请注意,如果您的应用依赖于 X-Appengine-Inbound-Appid
HTTP 标头(用于模块间通信),则必须使用 urlfetch
。
更改默认文件编码
App Engine 已将默认文件编码从 Java 7 中的 US-ASCII
更改为 Java 8 中的 UTF-8
。要在 Java 8 中将默认编码改回 US-ASCII
,请将以下内容添加到 appengine-web.xml
:
<system-properties>
<property name="appengine.file.encoding" value="US-ASCII"/>
</system-properties>
如果某些字符不属于 ASCII 集,而您的应用做出某些假设(如 someString.getBytes().length == someString.length()
),则可能会出现错误。在 US-ASCII 编码中,由于非 ASCII 字符会映射到“?”,因此该假设成立;但采用 UTF-8 编码时,该假设未必成立。
例如,如果打印调用 Éamonn.getBytes()
的十六进制字节结果,则采用 UTF-8 时的输出将是 c3 89 61 6d 6f 6e 6e
(Éamonn
),而采用 US-ASCII 时的输出将是 3f 61 6d 6f 6e 6e
(?amonn
),这是因为 É
的编码值不同。
充分利用 Java 8 运行时功能
以下是迁移到 Java 8 运行时的部分优势:
- Jetty 9 同时支持 Servlet 2.5 和 3.1 Web 应用,包括 servlet 注释。
- 所有标准 Java 类现在都可用,而且没有类许可名单。
/tmp
文件系统是可写的,这会占用应用的 RAM 分配。
- 现在可以在任何 Java 线程上执行网络 I/O。App Engine API 调用仍需要在请求线程或 Thread Manager API 创建的线程上执行。
- 现在支持完整的 Java 8 语言,包括 Stream API、Lambdas 和 Date/Time API。
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-09-04。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["很难理解","hardToUnderstand","thumb-down"],["信息或示例代码不正确","incorrectInformationOrSampleCode","thumb-down"],["没有我需要的信息/示例","missingTheInformationSamplesINeed","thumb-down"],["翻译问题","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-09-04。"],[[["\u003cp\u003eThis guide explains the process of migrating an App Engine app from the Java 7 runtime to the Java 8 runtime, which is based on OpenJDK.\u003c/p\u003e\n"],["\u003cp\u003eTo switch to the Java 8 runtime, add \u003ccode\u003e<runtime>java8</runtime>\u003c/code\u003e to your \u003ccode\u003eappengine-web.xml\u003c/code\u003e file and redeploy the app, while also addressing any usage of deprecated services, such as AppStats or Cloud Endpoints v1.\u003c/p\u003e\n"],["\u003cp\u003eJava 8 does not support some deprecated services from Java 7, and recommends migrating to alternatives like Cloud Trace and Cloud Endpoints v2, which may require some testing and changes in your app.\u003c/p\u003e\n"],["\u003cp\u003eFree apps using \u003ccode\u003ejava.net.HttpURLConnection\u003c/code\u003e for HTTP(S) requests must set \u003ccode\u003e<url-stream-handler>\u003c/code\u003e to \u003ccode\u003eurlfetch\u003c/code\u003e in \u003ccode\u003eappengine-web.xml\u003c/code\u003e to prevent runtime errors, or they may enable billing and use the \u003ccode\u003enative\u003c/code\u003e setting instead.\u003c/p\u003e\n"],["\u003cp\u003eMigrating to Java 8 provides advantages such as Jetty 9 support, access to all standard Java classes, a writable \u003ccode\u003e/tmp\u003c/code\u003e filesystem, and the full Java 8 language features, while also changing the default file encoding from \u003ccode\u003eUS-ASCII\u003c/code\u003e to \u003ccode\u003eUTF-8\u003c/code\u003e.\u003c/p\u003e\n"]]],[],null,["This page describes how to migrate your existing App Engine app from the Java 7\nruntime to the Java 8 runtime. Note that App Engine Java runtimes are based on\nOpenJDK.\n\nSpecifying the Java 8 runtime for your app\n\nTo run your app in the Java 8 runtime:\n\n1. Add `\u003cruntime\u003ejava8\u003c/runtime\u003e` to your `appengine-web.xml` file:\n\n \u003cappengine-web-app xmlns=\"http://appengine.google.com/ns\u003e/1.\u003c0\"\u003e\n ru\u003cntimejav\u003ea8/\u003cruntime\n \u003ethre\u003cadsafetrue/\u003et\u003chreadsafe\n /appengi\u003ene-web-app\n\n2. Redeploy your app.\n\nMigrating from unsupported services\n\nSome deprecated services available to the Java 7 runtime are not supported by\nthe Java 8 runtime. Google recommends that you migrate your application to the\nrecommended alternatives and test your app in the Java 7 runtime\nwith those changes prior to migrating to Java 8.\n\nThe following deprecated services are not available in the Java 8 runtime:\n\n| Deprecated service | Recommended alternative |\n|------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [Cloud Endpoints v1](/endpoints/docs/frameworks/legacy/v1/java) | [Migrate to v2](/endpoints/docs/frameworks/legacy/v1/java/migrating), the product has been renamed to Cloud Endpoints Frameworks. Note that this might require you to change your Web, Android, or iOS applications. |\n| [AppStats](/appengine/docs/legacy/standard/java/tools/appstats) (appengine-api-labs jar) | Migrate to [Cloud Trace](/trace/docs). The SDK generates an error for apps using the `com.google.appengine.tools.AppstatsFilter` class in the Java 8 runtime. Make sure you delete all references to `AppstatsFilter` from your `web.xml`. |\n\nRepackaged classes will require new import paths on Java 8. For example, if your\napp used `com.google.appengine.repackaged.com.google.common.base.Optional`,\nyou will need to import `com.google.appengine.repackaged.com.google.common.base.$Optional`,\nwith `$` prefixed to the class name.\n\nMigrating free apps that use java.net.HttpURLConnection\n\nIf your app does not have billing enabled and makes HTTP(S) requests using the\n`java.net.HttpURLConnection` class or a\n[Google client library](https://developers.google.com/api-client-library/java/apis/)\nthat uses that class, it will cause [runtime errors](/appengine/docs/legacy/standard/java/config/appref#url-stream-handler).\nTo avoid this, set the `\u003curl-stream-handler\u003e` to `urlfetch` in your app's\n`appengine-web.xml`: \n\n```xml\n\u003c?xml version=\"1.0\" encodin\u003eg\u003c=\"utf-8\"?\nappengine-web-app xmlns=\"http://app\u003eeng\u003cine.google\u003e.co\u003cm/ns/1.0\"\n !\u003e-- ... -\u003c-\n url-stream-hand\u003eler\u003curlfetch/u\u003er\u003cl-stream-handler\n \u003e !-- ... --\n/appengine-web-app\n```\n\nAlternatively, instead of specifying `urlfetch`, you can enable billing for your\napplication and use the default `native` setting. Your app should not incur\nany increase in costs from running on Java 7. Note that if your app relies on\nthe `X-Appengine-Inbound-Appid` HTTP header (used for Module-to-Module\ncommunication), `urlfetch` must be used.\n\nChanging the default file encoding\n\nApp Engine has changed the default file encoding from `US-ASCII` in Java 7 to\n`UTF-8` in Java 8. To change the default encoding back to\n`US-ASCII` in Java 8, add the following to your `appengine-web.xml`: \n\n \u003csystem-properties\u003e\n \u003cproperty name=\"appengine.file.encoding\" value=&\u003equ\u003cot;US-ASCII\"/\u003e\n /system-properties\n\nErrors may occur if some characters are not in the ASCII set and your\napplication makes certain assumptions, such as\n`someString.getBytes().length == someString.length()`. In US-ASCII encoding\nthis is true because non ASCII characters get mapped to \"?\", but this is not\nnecessarily true with UTF-8 encoding.\n\nFor example, if you print the hex bytes from calling\n`Éamonn.getBytes()`, with UTF-8 it will be:\n`c3 89 61 6d 6f 6e 6e` (`Éamonn`), whereas with US-ASCII you will get:\n`3f 61 6d 6f 6e 6e` (`?amonn`) due to the different encoding value of `É`.\n\nTaking full advantage of Java 8 runtime features\n\nThe following is a partial list of the advantages of migrating to the Java 8\nruntime:\n\n- Jetty 9 supports both Servlet 2.5 and 3.1 web applications, including servlet annotations.\n- All standard Java classes are now available, and there is no class allowlist.\n- The `/tmp` filesystem is writable - this takes up the app's RAM allocation.\n- Network I/O can now be performed on any Java thread. App Engine API calls still require being on either a Request Thread or a thread created by the Thread Manager API.\n- The full Java 8 language is now supported including the Stream API, Lambdas, and Date / Time API."]]