本页面介绍了如何将现有 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。