Environnement d'exécution Java 7

Avertissement : L'environnement d'exécution Java 7 est obsolète. Les déploiements d'applications sur l'environnement d'exécution Java 7 sont bloqués, et le SDK Java version 1.9.72 ou ultérieure n'autorise pas la création d'applications Java 7.

Si votre application utilise actuellement l'environnement d'exécution Java 7, elle sera automatiquement migrée vers l'environnement d'exécution Java 8. Google continuera à prendre en charge l'environnement d'exécution Java 7 conformément aux conditions d'utilisation. Vous devez migrer vers l'environnement d'exécution Java 8 dès que possible.

Avec App Engine, vous pouvez créer des applications Web qui utilisent l'infrastructure et les services évolutifs de Google.

Présentation

App Engine exécute votre application Web Java à l'aide d'une machine virtuelle Java 8 dans un environnement "bac à sable" sécurisé. App Engine appelle les classes de servlets de votre application pour gérer les requêtes et préparer les réponses dans cet environnement.

Le moteur d'exécution App Engine Java 7, basé sur OpenJDK 7, utilise le Java Servlet 2.5 standard pour les applications Web. Vous devez fournir les classes de servlets, les pages JSP, les fichiers statiques et de données ainsi que le descripteur de déploiement (fichier web.xml) et les autres fichiers de configuration de votre application, dans une structure de répertoires WAR standard. App Engine traite les requêtes en appelant les servlets en fonction du descripteur de déploiement.

L'environnement de "bac à sable" sécurisé isole votre application à des fins de service et de sécurité. Ainsi, les opérations effectuées par une application donnée n'ont aucune incidence sur les performances et l'évolutivité des autres applications. Par exemple, une application ne peut pas reproduire des fils de discussion, écrire des données sur le système de fichiers local ou établir des connexions réseau arbitraires. Elle ne peut pas non plus utiliser JNI ou un autre code natif. La machine virtuelle Java peut exécuter tout bytecode Java qui respecte les restrictions liées au bac à sable.

La plate-forme App Engine offre de nombreux services que votre code peut appeler. Votre application peut également configurer des tâches planifiées qui s'exécutent à des intervalles donnés.

Le tutoriel de l'application Java Guestbook fournit une introduction au développement d'applications Web avec les technologies Java et App Engine.

Sélectionner l'environnement d'exécution Java 8

L'API App Engine pour Java est représentée par le fichier appengine-api-*.jar inclus dans le SDK App Engine dans le cadre du SDK Cloud (où * représente la version de l'API et du SDK App Engine).

Sélectionnez la version de l'API utilisée par votre application en incluant ce fichier JAR dans le répertoire WEB-INF/lib/ de l'application, ou utilisez Maven pour gérer les dépendances. Si une nouvelle version de l'environnement d'exécution Java, comportant des modifications non compatibles avec les applications existantes, est mise à disposition, cet environnement portera un nouveau numéro de version. Votre application continuera à utiliser la version précédente jusqu'à ce que vous remplaciez le fichier JAR par la nouvelle version (à partir d'un kit de développement logiciel App Engine plus récent) et que vous téléchargiez à nouveau l'application.

Utiliser Maven pour gérer les dépendances

Vous pouvez utiliser Maven pour gérer toutes les dépendances. Par exemple, cette entrée pom.xml inclut la dernière API App Engine (Rappengine-api-1.0-sdk) disponible auprès de Maven Central :

<dependency>
    <groupId>com.google.appengine</groupId>
    <artifactId>appengine-api-1.0-sdk</artifactId>
    <version><span class="notranslate exporttrans-dynamic">print setvar.appengine_java_version</span></version>
</dependency>

Bac à sable

Pour qu'App Engine puisse distribuer des requêtes aux applications de plusieurs serveurs Web, et pour éviter qu'une application interfère avec une autre, l'application s'exécute dans un environnement de "bac à sable" restreint. Dans cet environnement, l’application peut exécuter du code, stocker et interroger les données dans Cloud Datastore, utiliser les services de messagerie, de récupération d’URL et d’utilisateur d’App Engine, examiner la demande Web de l’utilisateur et préparer la réponse.

Une application App Engine ne peut pas :

  • écrire sur le système de fichiers. Les applications doivent utiliser Cloud Datastore pour stocker des données persistantes. La lecture à partir du système de fichiers est autorisée, et tous les fichiers de l'application transférés avec cette dernière sont disponibles.

  • Répondre lentement. Une requête Web vers une application doit être traitée en quelques secondes. Les processus qui mettent trop de temps à répondre sont interrompus afin d'éviter de surcharger le serveur Web.

  • effectuer d'autres types d'appels système.

Système de fichiers

Une application Java ne peut utiliser aucune classe utilisée pour écrire dans le système de fichiers, telle que java.io.FileWriter. Une application peut lire ses propres fichiers à partir du système de fichiers à l'aide de classes telles que java.io.FileReader. Elle peut également accéder à ses propres fichiers comme à des ressources, par exemple avec Class.getResource() ou ServletContext.getResource().

Seuls les fichiers qui sont considérés comme des "fichiers ressources" sont accessibles à l'application via le système de fichiers. Par défaut, tous les éléments du fichier WAR sont des "fichiers de ressources". Vous pouvez en exclure certains à l'aide du fichier appengine-web.xml.

java.lang.System

Les fonctionnalités de la classe java.lang.System qui ne s'appliquent pas à App Engine sont désactivées.

Les méthodes System suivantes n'ont aucun effet dans App Engine : exit(), gc(), runFinalization(), runFinalizersOnExit()

Les méthodes System suivantes renvoient null : inheritedChannel() et console().

Une application ne peut pas fournir du code JNI natif, ni l'appeler directement. Les méthodes System suivantes génèrent une exception java.lang.SecurityException : load(), loadLibrary() et setSecurityManager().

Réflexion

Une application dispose d'un accès complet, illimité et réflexif à ses propres classes.

Elle peut interroger n'importe quel membre privé, appeler la méthode java.lang.reflect.AccessibleObject.setAccessible() et lire/définir des membres privés.

Une application peut également réfléchir sur les classes JRE et API, telles que java.lang.String et javax.servlet.http.HttpServletRequest. Cependant, elle ne peut accéder qu'aux membres publics de ces classes, pas aux membres protégés ni privés.

Une application ne peut pas refléter une autre classe qui ne lui appartient pas, et elle ne peut pas utiliser la méthode setAccessible() pour contourner ces restrictions.

Charger des classes personnalisées

App Engine propose une prise en charge complète du chargement de classes personnalisées. Une application est autorisée à définir sa propre sous-classe de ClassLoader afin d'implémenter une logique de chargement des classes spécifique à l'application. Gardez toutefois à l'esprit qu'App Engine, ignorant les chargeurs de classe, attribue les mêmes permissions à toutes les classes chargées par votre application. Si vous chargez des classes personnalisées, soyez prudent lorsque vous chargez du code tiers non sécurisé.

Ordre des fichiers JAR pour le chargement des classes

Parfois, il peut être nécessaire de redéfinir l'ordre dans lequel les fichiers JAR sont analysés pour identifier les classes afin de résoudre les conflits entre noms de classes. Vous avez donc la possibilité d'accorder la priorité à certains fichiers JAR en ajoutant une section <class-loader-config> contenant des éléments <priority-specifier> dans le fichier appengine-web.xml. Exemple :

<class-loader-config>
  <priority-specifier filename="mailapi.jar"/>
</class-loader-config>

Dans cet exemple, "mailapi.jar" est le premier fichier JAR dans lequel il faut rechercher des classes, excluant ainsi les fichiers du répertoire war/WEB-INF/classes/.

Si plusieurs fichiers JAR sont hiérarchisés, leur ordre de chargement initial (l'un par rapport à l'autre) sera utilisé. En d'autres termes, l'ordre des éléments <priority-specifier> n'est pas pris en considération.

Liste blanche JRE

L'accès aux classes de la bibliothèque Java standard (l'environnement d'exécution Java, ou JRE [Java Runtime Environment]) est limité aux classes dans la liste blanche JRE d'App Engine.

Incompatibilité des fichiers JAR signés

La précompilation d'App Engine n'est pas compatible avec les fichiers JAR signés. Si votre application est précompilée (configuration par défaut), elle ne sera pas en mesure de charger des fichiers JAR. Si l'application tente de charger un fichier JAR signé, App Engine générera une exception au moment de l'exécution, comme

java.lang.SecurityException: SHA1 digest error for com/example/SomeClass.class
    at com.google.appengine.runtime.Request.process-d36f818a24b8cf1d(Request.java)
    at sun.security.util.ManifestEntryVerifier.verify(ManifestEntryVerifier.java:210)
    at java.util.jar.JarVerifier.processEntry(JarVerifier.java:218)
    at java.util.jar.JarVerifier.update(JarVerifier.java:205)
    at java.util.jar.JarVerifier$VerifierStream.read(JarVerifier.java:428)
    at sun.misc.Resource.getBytes(Resource.java:124)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:273)
    at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:266)

Il existe deux façons de contourner ce problème :

Fils de discussion

Une application Java peut créer un fil de discussion, à condition de respecter certaines restrictions. Ces fils de discussion ne peuvent pas perdurer au-delà de la requête qui les a créés.

Une application peut :

Vous devez cependant utiliser l'une des méthodes du gestionnaire ThreadManager pour créer vos fils de discussion. Vous ne pouvez pas appeler new Thread() vous-même, ni utiliser le générateur de fils de discussion par défaut.

Une application peut exécuter des opérations par rapport au fil de discussion actuel, comme thread.interrupt().

Chaque requête est restreinte à 50 fils de discussion simultanés. L'environnement d'exécution Java signalera une erreur java.lang.IllegalStateException si vous essayez de créer plus de 50 fils de discussion en une seule requête.

Lorsque vous utilisez des fils de discussion, utilisez des objets d'accès simultané de haut niveau, tels que Executor et Runnable. Ceux-ci s’occupent de nombreux détails de concurrence subtils, mais importants, tels que les interruptions ainsi que la planification et la tenue des registres.

Fils de discussion en arrière plan

Le code exécuté sur des instances de redimensionnement manuel ou de base peut démarrer un fil de discussion en arrière-plan pouvant survivre à la requête qui le génère. Cela permet aux instances d'effectuer des tâches périodiques ou planifiées arbitraires ou de continuer à travailler en arrière-plan après le retour d'une requête à l'utilisateur.

La simultanéité Java peut entraîner des problèmes difficiles à résoudre. Pour éviter l'utilisation de fils de discussion, envisagez de recourir aux files d'attente de tâches, aux tâches planifiées ou à Pub/Sub.

Les entrées de journalisation d'un fil de discussion en arrière-plan sont indépendantes de celles du fil de discussion en création. Vous pouvez en apprendre plus sur les fils de discussion en arrière-plan dans la documentation ThreadManager d'App Engine.

import com.google.appengine.api.ThreadManager;
import java.util.concurrent.atomic.AtomicLong;

AtomicLong counter = new AtomicLong();

Thread thread = ThreadManager.createBackgroundThread(new Runnable() {
  public void run() {
    try {
      while (true) {
        counter.incrementAndGet();
        Thread.sleep(10);
      }
    } catch (InterruptedException ex) {
      throw new RuntimeException("Interrupted in loop:", ex);
    }
  }
});
thread.start();

Si le code exécuté dans un service de mise à l'échelle automatique tente de démarrer un fil de discussion en arrière-plan, une exception est levée.

Le nombre maximal de fils de discussion en arrière-plan simultanés créés par l'API App Engine est de 10 par instance. (Cette limite ne s'applique pas aux fils de discussion Java normaux non liés à l'API App Engine.)

Outils

IDE compatibles

Cloud Tools for Eclipse ajoute de nouveaux assistants de projet et de nouvelles configurations de débogage à vos projets Eclipse IDE pour App Engine. Vous pouvez déployer vos projets App Engine en production directement depuis Eclipse.

Cloud Tools for IntelliJ vous permet d'exécuter et de déboguer des applications App Engine dans IntelliJ IDEA. Vous pouvez déployer vos projets App Engine en production sans quitter l'IDE.

Outils de compilation compatibles

Pour accélérer votre processus de développement, vous pouvez utiliser les plug-ins App Engine pour Apache Maven ou Gradle :

Serveur de développement local

Le serveur de développement exécute votre application sur votre ordinateur local à des fins de développement et de test. Le serveur simule les services Cloud Datastore. Le serveur de développement peut également générer une configuration pour les index Cloud Datastore basée sur les requêtes effectuées par l'application lors des tests.

AppCfg

AppCfg est inclus dans la version autonome du SDK App Engine pour Java. Il s'agit d'un outil polyvalent qui gère les interactions en ligne de commande avec votre application s'exécutant sur App Engine. AppCfg peut importer votre application vers App Engine, ou simplement mettre à jour la configuration des index Cloud Datastore pour vous permettre de créer des index avant de mettre à jour le code. Il peut également télécharger les données de journalisation de l'application de sorte que vous puissiez analyser ses performances à l'aide de vos propres outils.

Concurrence et latence

La latence de votre application a le plus grand impact sur le nombre d'instances nécessaires pour desservir votre trafic. Si vous traitez les demandes rapidement, une seule instance peut gérer un grand nombre de demandes.

Les instances à un seul fil de discussion peuvent gérer une requête simultanée. Par conséquent, il existe une relation directe entre le temps de latence et le nombre de demandes pouvant être traitées sur l’instance par seconde. Par exemple, une latence de 10 ms équivaut à 100 requêtes/seconde/instance.

Les instances à plusieurs fils de discussion peuvent gérer de nombreuses demandes simultanées. Par conséquent, il existe une relation directe entre le temps de processeur consommé et le nombre de requêtes par seconde.

Les applications Java sont compatibles avec les requêtes simultanées. Ainsi, une même instance peut gérer de nouvelles requêtes en attendant que les autres requêtes soient terminées. La simultanéité réduit considérablement le nombre d'instances requises par votre application, mais vous devez concevoir votre application pour le fonctionnement multithread.

Par exemple, si une instance B4 (environ 2,4 GHz) consomme 10 Mcycles/demande, vous pouvez traiter 240 demandes/seconde/instance. Si elle consomme 100 Mcycles/demande, vous pouvez traiter 24 demandes/seconde/instance. Ces chiffres sont le cas idéal mais sont assez réalistes par rapport à ce que vous pouvez accomplir sur une instance.

Cette page vous a-t-elle été utile ? Évaluez-la :

Envoyer des commentaires concernant…

Environnement standard App Engine pour Java 8