Réempaqueter un fichier WAR dans un fichier JAR

Si vous migrez vers la dernière version Java compatible et que votre application n'utilise pas les anciens services groupés, vous devez réempaqueter votre application Web App Engine dans un fichier JAR exécutable.

Votre application doit comporter une classe Main qui démarre un serveur Web répondant aux requêtes HTTP sur le port 8080, qui peut être spécifié par la variable d'environnement PORT.

Exemple :

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.Configuration.ClassList;
import org.eclipse.jetty.webapp.WebAppContext;

/** Simple Jetty Main that can execute a WAR file when passed as an argument. */
public class Main {

  public static void main(String[] args) throws Exception {
    if (args.length != 1) {
      System.err.println("Usage: need a relative path to the war file to execute");
      System.exit(1);
    }
    System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.StrErrLog");
    System.setProperty("org.eclipse.jetty.LEVEL", "INFO");

    // Create a basic Jetty server object that will listen on port defined by
    // the PORT environment variable when present, otherwise on 8080.
    int port = Integer.parseInt(System.getenv().getOrDefault("PORT", "8080"));
    Server server = new Server(port);

    // The WebAppContext is the interface to provide configuration for a web
    // application. In this example, the context path is being set to "/" so
    // it is suitable for serving root context requests.
    WebAppContext webapp = new WebAppContext();
    webapp.setContextPath("/");
    webapp.setWar(args[0]);
    ClassList classlist = ClassList.setServerDefault(server);

    // Enable Annotation Scanning.
    classlist.addBefore(
        "org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
        "org.eclipse.jetty.annotations.AnnotationConfiguration");

    // Set the the WebAppContext as the ContextHandler for the server.
    server.setHandler(webapp);

    // Start the server! By using the server.join() the server thread will
    // join with the current thread. See
    // "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()"
    // for more details.
    server.start();
    server.join();
  }
}

Exemple de migration WAR (Java 21)

Les instructions suivantes montrent comment réempaqueter une application WAR hello-world App Engine en tant que fichier JAR à exécuter sur l'environnement d'exécution Java 21.

La migration utilise l'artefact appengine-simple-jetty-main. Cela fournit une classe Main avec un serveur Web Jetty simple qui charge un fichier WAR et empaquette votre application dans un fichier JAR exécutable :

  1. Clonez l'artefact Embedded Jetty Server sur votre ordinateur local :

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

    Vous pouvez également télécharger l'exemple en tant que fichier ZIP et l'extraire.

  2. Accédez au répertoire qui contient l'exemple de code :

    cd java-docs-samples/flexible/repacking-legacy-applications/appengine-simple-jetty-main/
    
  3. Créez le fichier JAR de l'exécuteur Jetty :

    mvn install
    

    Cela génère jetty-jar-with-dependencies.jar dans votre répertoire target/.

  4. Configurez le fichier de compilation pom.xml pour le serveur Jetty :

    • Propriétés du compilateur (Java 21) :
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <jetty.version>9.4.57.v20241219</jetty.version>
      </properties>
    • Dépendances Jetty intégrées :
      <dependencies>
        <!-- Embedded Jetty dependencies -->
        <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-server</artifactId>
          <version>${jetty.version}</version>
        </dependency>
        <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-webapp</artifactId>
          <version>${jetty.version}</version>
          <type>jar</type>
        </dependency>
        <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-util</artifactId>
          <version>${jetty.version}</version>
        </dependency>
        <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>jetty-annotations</artifactId>
          <version>${jetty.version}</version>
        </dependency>
        <!-- extra explicit dependency needed because there is a JSP in the sample-->
        <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>apache-jsp</artifactId>
          <version>${jetty.version}</version>
        </dependency>
      </dependencies>
    • Configuration de maven-assembly-plugin :
      
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.0.0</version>
        <configuration>
          <finalName>jetty</finalName>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <archive>
            <manifest>
              <mainClass>com.example.appengine.jetty.Main</mainClass>
            </manifest>
          </archive>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      
  5. Placez le fichier jetty-jar-with-dependencies.jar généré et le fichier WAR de votre application. Par exemple, helloworld.war dans le même répertoire.

  6. Créez un fichier app.yaml dans le répertoire de votre application pour spécifier l'environnement d'exécution Java 21 et un élément entrypoint pour appeler le fichier jetty-jar-with-dependencies.jar et transmettre votre fichier WAR en tant qu'argument :

    runtime: java21
    entrypoint: 'java -jar jetty-jar-with-dependencies.jar helloworld.war'
    
  7. Pour exécuter votre application localement, procédez comme suit :

    1. Démarrez le serveur avec votre fichier WAR en tant qu'argument :

      java -jar jetty-jar-with-dependencies.jar helloworld.war
      
    2. Dans votre navigateur Web, saisissez l'adresse suivante :

      http://localhost:8080

  8. Pour déployer votre application, procédez comme suit :

    Outils gcloud

    gcloud app deploy

    Plug-in Maven

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

    Remplacez PROJECT_ID par l'ID de votre projet Google Cloud . Si votre ID de projet est déjà inclus dans le fichier pom.xml, vous n'avez pas besoin d'inclure la propriété -Dapp.deploy.projectId dans la commande que vous exécutez.