从 Java 7 运行时迁移到 Java 8 运行时

本页面介绍了如何将现有 App Engine 应用从 Java 7 运行时迁移到 Java 8 运行时。请注意,App Engine Java 运行时基于 OpenJDK。

为您的应用指定 Java 8 运行时

要在 Java 8 运行时中运行您的应用,请执行以下操作:

  1. <runtime>java8</runtime> 添加到 appengine-web.xml 文件中:

    <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
      <runtime>java8</runtime>
      <threadsafe>true</threadsafe>
    </appengine-web-app>
  2. 重新部署您的应用。

从不受支持的服务迁移

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。