将 WAR 文件重新封装为 JAR 文件

如果您要迁移到受支持的最新 Java 版本,并且您的应用不使用旧版捆绑服务,您必须将 App Engine Java 8 Web 应用重新封装为可执行的 JAR 文件。

您的应用必须具有一个 Main 类,该类会启动一个 Web 服务器以响应由 PORT 环境变量指定的端口 8080 上的 HTTP 请求。

例如:

import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;

public class Main {

  public static void main(String[] args) throws IOException {
    // Create an instance of HttpServer bound to port defined by the 
    // PORT environment variable when present, otherwise on 8080.
    int port = Integer.parseInt(System.getenv().getOrDefault("PORT", "8080"));
    HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);

    // Set root URI path.
    server.createContext("/", (var t) -> {
      byte[] response = "Hello World from Google App Engine Java 11.".getBytes();
      t.sendResponseHeaders(200, response.length);
      try (OutputStream os = t.getResponseBody()) {
        os.write(response);
      }
    });

    // Start the server.
    server.start();
  }
}

WAR 迁移示例 (Java 11)

以下说明演示了如何将 App Engine Java 8 hello-world 应用重新封装为 JAR 以便在 Java 11 运行时环境中运行。

该迁移使用 appengine-simple-jetty-main 工件。这为 Main 类提供了一个简单的 Jetty Web 服务器,用来加载 WAR 文件并将您的应用封装成可执行的 JAR 文件:

  1. 将嵌入式 Jetty 服务器工件克隆到本地机器:

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples
    

    或者,您也可以下载该示例的 zip 文件并将其解压缩。

  2. 转到包含示例代码的目录:

    cd java-docs-samples/appengine-java11/appengine-simple-jetty-main/
    
  3. 在本地安装依赖项:

    mvn install
    
  4. 将以下代码添加到您的项目 pom.xml 文件中:

    • appengine-simple-jetty-main 依赖项:
      <dependency>
        <groupId>com.example.appengine</groupId>
        <artifactId>simple-jetty-main</artifactId>
        <version>1</version>
        <scope>provided</scope>
      </dependency>
    • maven-dependency 插件:
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>3.6.1</version>
        <executions>
          <execution>
            <id>copy</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <outputDirectory>
                ${project.build.directory}/appengine-staging
              </outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
      App Engine 将部署位于 ${build.directory}/appengine-staging 目录中的文件。通过将 maven-dependency 插件添加到您的版本中,App Engine 会将您指定的依赖项安装到正确的文件夹中。
  5. app.yaml 文件中创建一个 entrypoint 元素,以调用 appengine-simple-jetty-main 对象并将 WAR 文件作为参数传递。如需查看示例,请参阅 helloworld-servlet 示例 app.yaml 文件:

    runtime: java11
    entrypoint: 'java -cp "*" com.example.appengine.jetty.Main helloworld.war'
  6. 如需在本地运行应用,请执行以下操作:

    1. 封装应用:

      mvn clean package
      
    2. 使用 WAR 文件作为参数启动服务器。

      例如,您可以通过从 java-docs-samples/appengine-java11/appengine-simple-jetty-main/ 文件夹运行以下命令,来启动 helloworld-servlet 示例中的服务器:

      mvn exec:java -Dexec.args="../helloworld-java8/target/helloworld.war"
      
    3. 在网络浏览器中输入以下地址:

      http://localhost:8080

  7. 要部署应用,请运行以下命令:

    gcloud 工具

    gcloud app deploy

    Maven 插件

    mvn package appengine:deploy -Dapp.deploy.projectId=PROJECT_ID

    PROJECT_ID 替换为您的 Google Cloud 项目的 ID。 如果您的 pom.xml 文件已经指定了您的项目 ID,则您无需在运行的命令中添加 -Dapp.deploy.projectId 属性。