WAR ファイルを JAR ファイルに再パッケージ化する

サポートされている最新バージョンの Java に移行するときに、アプリで以前のバンドル サービスを使用していない場合は、App Engine Java 8 ウェブ アプリケーションを実行可能な JAR ファイルに再パッケージ化する必要があります。

アプリケーションには、PORT 環境変数で指定されたポート(通常は 8081)の HTTP リクエストに応答するウェブサーバーを起動する Main クラスが必要です。

次に例を示します。

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 アプリケーションを Java 11 ランタイムで実行する JAR として再パッケージ化する方法を説明します。

この移行では appengine-simple-jetty-main アーティファクトを使用します。これにより、Main クラスにシンプルな Jetty ウェブサーバーが与えられます。Jetty ウェブサーバーは 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 プラグインをビルドに追加すると、指定した依存関係が正しいフォルダにインストールされます。
  5. entrypoint 要素を app.yaml ファイルに作成して 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 プロパティを含める必要はありません。