Remarque :
- Ce tutoriel est disponible dans un environnement de laboratoire gratuit fourni par Oracle.
- Il utilise des exemples de valeur pour les informations d'identification, la location et les compartiments Oracle Cloud Infrastructure. A la fin de l'exercice, remplacez ces valeurs par celles propres à votre environnement cloud.
Introduction à GraalVM Native Image
Introduction
Cet atelier vous guide étape par étape dans le processus de création d'une application Java native dans le cloud avec GraalVM Native Image. Il s'adresse aux développeurs connaissant Java.
La technologie GraalVM Native Image compile le code Java à l'avance dans un fichier exécutable autonome. Seul le code requis lors de l'exécution par l'application est ajouté au fichier exécutable.
Un fichier exécutable produit par Native Image présente plusieurs avantages importants, en ce sens qu'il :
- Utilise une fraction des ressources requises par la JVM. L'exécution est donc moins coûteuse
- Commence en millisecondes
- Performances de pointe immédiatement, sans réchauffement
- Peut être packagé dans une image de conteneur légère pour un déploiement plus rapide et plus efficace
- Présente une surface d'attaque réduite (plus importante dans les exercices à venir)
Nombre des principaux cadres de travail de microservices prennent en charge la compilation anticipée avec GraalVM Native Image, y compris Micronaut, Spring, Helidon et Quarkus.
En outre, il existe des modules d'extension Maven et Gradle pour Native Image afin que vous puissiez facilement créer, tester et exécuter des applications Java en tant que fichiers exécutables.
Remarque : Oracle Cloud Infrastructure (OCI) fournit GraalVM Enterprise sans frais supplémentaires.
Temps de laboratoire estimé : 45 minutes
Objectifs du laboratoire
Dans cet exercice, vous allez effectuer les tâches suivantes :
- Connexion à un hôte distant dans Oracle Cloud : vous développerez votre application sur un hôte de calcul Oracle Cloud
- Créer et exécuter une application Java à l'aide de GraalVM
- Transformer une application Java en fichier exécutable à l'aide de GraalVM Native Image
- Créer un fichier exécutable qui fonctionne avec les fonctionnalités dynamiques de Java
- Utiliser le module d'extension GraalVM Maven pour créer des fichiers exécutables avec GraalVM Native Image
REMARQUE : Si l'icône de l'ordinateur portable apparaît dans l'exercice, vous devez exécuter une commande, par exemple. Gardez un oeil pour cela.
# This is where we you will need to do something
Etape 1 : connexion à un hôte distant et vérification de l'environnement de développement
Votre environnement de développement est fourni par un hôte distant : une instance de calcul OCI avec Oracle Linux 8, 1 UC et 32 Go de mémoire.
L'environnement de bureau Luna Labs s'affichera avant que l'hôte distant soit prêt, ce qui peut prendre jusqu'à deux minutes.
La connexion à votre hôte distant s'effectue via l'exécution d'un script de configuration dans votre environnement Luna Desktop. Ce script est disponible via l'onglet Ressources
-
Dans le bureau, cliquez deux fois sur l'icône Luna-Lab.html. La page apparaît pour afficher les informations d'identification et les informations d'identification Oracle Cloud Infrastructure propres à l'exercice.
-
L'onglet Ressources s'affiche. Le graphique affiché en regard du titre Ressources tourne tandis que l'instance de calcul est provisionnée dans le cloud de thé.
-
Une fois l'instance provisionnée, cette opération peut prendre jusqu'à 2 minutes. Les éléments suivants apparaissent dans l'onglet Ressources.
-
Copiez le script de configuration, qui configure votre environnement VS Code, à partir de l'onglet Ressources. Cliquez sur le lien Visualiser les détails pour afficher la configuration. Copiez-le comme indiqué dans la capture d'écran ci-dessous.
-
Ouvrez un terminal, comme indiqué dans la capture d'écran ci-dessous :
-
Collez le code de configuration dans le terminal, qui va ouvrir VS Code pour vous.
Et tu as fini ! Félicitations. Vous êtes maintenant connecté à un hôte distant dans Oracle Cloud !
Remarque sur l'environnement de développement
You will use GraalVM Enterprise 21, as the Java platform for this lab. GraalVM is a high performance JDK distribution from Oracle built on the trusted and secure Oracle Java SE.
Votre environnement de développement est préconfiguré avec GraalVM et les outils Native Image requis pour cet atelier.
Vous pouvez facilement vérifier qu'en exécutant ces commandes dans le terminal, vous pouvez créer un terminal à partir du code VS, Terminal > New Terminal
:
java -version
native-image --version
Etape 2 : création et exécution d'une application de démonstration
Nous utiliserons une application de démonstration pour présenter GraalVM Native Image : une application de ligne de commande Java qui compte le nombre de fichiers contenus dans le répertoire actuel et ses sous-répertoires. En complément, l'application calcule également la taille totale des fichiers.
Le code source de l'application est disponible sur l'hôte distant.
Remarque sur l'application de démonstration
L'application se compose de deux fichiers Java qui se trouvent dans le répertoire src
:
App.java
: wrapper pour la classeListDir
.ListDir.java
: effectue tout le travail. Il compte les fichiers et résume la sortie.
L'application peut être créée manuellement ou à l'aide de profils Maven. La configuration de build Maven est fournie par le fichier pom.xml
. Les profils Maven sont un excellent moyen d'avoir différentes configurations de build dans un seul fichier pom.xml
. Pour en savoir plus sur les profils Maven, cliquez ici.
Vous pouvez parcourir les fichiers figurant dans le code VS ouvert.
Plusieurs profils seront utilisés dans cet exercice, chacun ayant un but particulier :
native
: ce profil crée un fichier exécutable à l'aide de GraalVM Native Image.java_agent
: ce profil crée l'application Java avec un agent de suivi qui suit toutes les utilisations du code dynamique dans votre application et capture ces informations dans des fichiers de configuration. Pour en savoir plus, consultez la suite.
Vous utilisez un profil Maven particulier en le transmettant en tant que paramètre à la commande mvn
. Le nom du profil est ajouté à la fin de l'indicateur -P
. Vous pouvez exécuter les commandes suivantes depuis le terminal dans le code VS.
L'exemple ci-dessous montre comment appeler un profil native
lors de la création avec Maven :
mvn clean package -Pnative
Maintenant que vous avez une connaissance de base de ce que l'application exécute pour voir comment elle fonctionne.
-
Créez le projet et exécutez-le, à partir du terminal que nous avons ouvert dans VS Code :
mvn clean package exec:exec
La commande ci-dessus :
- Nettoie le projet pour enlever les artefacts générés ou compilés.
- Crée un fichier JAR exécutable contenant l'application. Ce fichier JAR sera utilisé ultérieurement par Native Image.
- Exécute l'application en exécutant le module d'extension
exec
.
Les éléments suivants doivent être inclus dans la sortie générée (le nombre de fichiers signalés par l'application peut varier) :
Counting directory: . Total: 15 files, total size = 511.9 KiB [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
Etape 3 : transformer une application Java en fichier exécutable
Vous allez ensuite créer une version exécutable de l'application à l'aide de GraalVM Native Image. Pour rappel, GraalVM Native Image est une technologie de compilation à l'avance qui convertit votre application Java en un fichier exécutable autonome qui ne nécessite pas d'exécution de JDK, rapide à démarrer et efficace.
GraalVM Native Image est préinstallé sur l'hôte distant.
-
Pour commencer, vérifiez que vous disposez d'un fichier JAR compilé dans votre répertoire
target
:ls ./target drwxrwxr-x 1 krf krf 4096 Mar 4 11:12 archive-tmp drwxrwxr-x 1 krf krf 4096 Mar 4 11:12 classes drwxrwxr-x 1 krf krf 4096 Mar 4 11:12 generated-sources -rw-rw-r-- 1 krf krf 496273 Mar 4 11:38 graalvmnidemos-1.0-SNAPSHOT-jar-with-dependencies.jar -rw-rw-r-- 1 krf krf 7894 Mar 4 11:38 graalvmnidemos-1.0-SNAPSHOT.jar drwxrwxr-x 1 krf krf 4096 Mar 4 11:12 maven-archiver drwxrwxr-x 1 krf krf 4096 Mar 4 11:12 maven-status
Le fichier dont vous aurez besoin est
graalvmnidemos-1.0-SNAPSHOT-jar-with-dependencies.jar
. -
Générez un fichier exécutable à partir de la ligne de commande. Vous n'avez pas besoin d'utiliser le module d'extension Maven pour utiliser GraalVM Native Image, mais cela peut vous aider. Exécutez la commande suivante à partir du répertoire racine du projet,
demo
:native-image -jar ./target/graalvmnidemos-1.0-SNAPSHOT-jar-with-dependencies.jar --no-fallback -H:Class=oracle.App -H:Name=file-count
Cette opération génère un fichier exécutable appelé
file-count
dans le répertoire en cours. -
Exécutez ce fichier exécutable comme suit :
./file-count
-
L'heure actuelle de l'application. Commencez par l'exécuter en tant que fichier exécutable, puis à l'aide de la commande
java
standard :time ./file-count
time java -cp ./target/graalvmnidemos-1.0-SNAPSHOT-jar-with-dependencies.jar oracle.App
Le fichier exécutable, généré par la commande
native-image
, s'exécute beaucoup plus rapidement que l'application Java correspondante.
Examinons plus en détail la façon dont vous avez créé le fichier exécutable.
Quels sont les paramètres que vous avez transmis à la commande native-image
à l'étape 2 indiqués ?
-jar
: indiquez l'emplacement du fichier JAR contenant l'application Java. (Vous pouvez également spécifier la variable d'environnement classpath avec-cp
.)--no-fallback
: ne génère pas d'image de restauration. (Une image de secours nécessite une JVM pour l'exécuter et vous n'en avez pas besoin.)-H:Class
: indiquez la classe qui fournit la méthode de point d'entrée (méthodemain
).-H:Name
: indiquez le nom du fichier exécutable de sortie.
La documentation complète est disponible ici.
Vous pouvez également exécuter l'outil native-image
à l'aide du module d'extension Maven de GraalVM Native Image. Le fichier de projet pom.xml
(configuration Maven) contient le fragment de code suivant qui explique comment créer un fichier exécutable à l'aide du module d'extension :
<!-- Native Image -->
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native.maven.plugin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>build-native</id>
<goals>
<goal>build</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<skip>false</skip>
<imageName>${exe.file.name}</imageName>
<mainClass>${app.main.class}</mainClass>
<buildArgs>
<buildArg>--no-fallback</buildArg>
<buildArg>--report-unsupported-elements-at-runtime</buildArg>
</buildArgs>
</configuration>
</plugin>
Le module d'extension Maven Native Image effectue la lourde tâche de création du fichier exécutable. Vous pouvez la désactiver à l'aide de la balise <skip>true</skip>
. Vous pouvez également transmettre des paramètres à native-image
via les balises <buildArgs/>
.
La documentation complète du module d'extension GraalVM Native Image est disponible ici.
Pour créer le fichier exécutable à l'aide du profil Maven, exécutez la commande suivante :
mvn clean package -Pnative
La création Maven place le fichier exécutable file-count
dans le répertoire target
.
Vous pouvez exécuter le fichier exécutable comme suit :
./target/file-count
Etape 4 : utilisation de la réflexion - Ajout d'une dépendance à Log4J
Cette étape consiste à créer un fichier exécutable qui fonctionne avec les fonctionnalités dynamiques de Java.
Supposons que vous souhaitiez ajouter une bibliothèque ou un code à votre application qui repose sur la réflexion. La structure de journalisation Log4J est un bon candidat pour tester la réflexion. Il est déjà ajouté en tant que dépendance dans le fichier pom.xml
du projet :
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
Pour modifier l'application afin qu'elle utilise log4j
, modifiez le fichier ListDir.java
et annulez le commentaire de quelques lignes.
-
Ouvrez le fichier
ListDir.java
à l'aide du code VS. -
Annulez le commentaire de la ligne qui déclare l'import
log4j
, puis annulez le commentaire des lignes suivantes ://import org.apache.log4j.Logger;
//final static Logger logger = Logger.getLogger(ListDir.class);
/* // Add some logging if(logger.isDebugEnabled()){ logger.debug("Processing : " + dirName); } */
/* // Add some logging if(logger.isDebugEnabled()){ logger.debug("Processing : " + f.getAbsolutePath()); } */
-
Enregistrez le fichier
Une fois que vous avez ajouté la journalisation à votre application, vous pouvez visualiser le résultat de vos modifications en les reconstruisant et en les exécutant.
mvn clean package exec:exec
Vous devriez voir le même type de sortie que précédemment vu, mais avec l'ajout d'une journalisation supplémentaire.
-
Ensuite, créez un fichier exécutable à l'aide du profil Maven :
mvn clean package -Pnative
-
Exécutez le fichier exécutable que vous avez créé, qui contient désormais la journalisation :
./target/file-count
Cela génère une erreur :
Exception in thread "main" java.lang.NoClassDefFoundError at org.apache.log4j.Category.class$(Category.java:118) at org.apache.log4j.Category.<clinit>(Category.java:118) at java.lang.Class.ensureInitialized(DynamicHub.java:552) at oracle.ListDir.<clinit>(ListDir.java:75) at oracle.App.main(App.java:63) Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Category at java.lang.Class.forName(DynamicHub.java:1433) at java.lang.Class.forName(DynamicHub.java:1408) ... 5 more
Que t'est-il arrivé ?
Utiliser les fonctionnalités dynamiques de Java
Cette exception est due à l'ajout de la bibliothèque Log4J car elle repose sur la réflexion.
L'outil native-image
effectue une analyse statique agressive pour voir quelles classes sont utilisées dans l'application. Pour les classes non utilisées, l'outil suppose qu'elles ne sont pas nécessaires. Il s'agit de l'hypothèse "closed world" : tout ce qui doit être chargé doit être connu lors de la création d'un fichier exécutable. S'il ne peut pas être trouvé par analyse statique, il ne sera pas inclus dans le fichier exécutable.
La réflexion est une fonctionnalité de base de Java. Comment pouvez-vous utiliser la réflexion et tirer parti des accélérations offertes par GraalVM Native Image ? Vous devez disposer d'un moyen de faire connaître à l'outil native-image
toutes les utilisations de la réflexion.
Par chance, l'outil native-image
peut lire dans des fichiers de configuration qui spécifient toutes les classes référencées par réflexion.
Vous pouvez le faire manuellement, ou l'agent de trace Java fourni avec l'exécution Java GraalVM peut le faire pour vous. L'agent génère des fichiers JSON qui enregistrent toutes les instances de réflexion, JNI, proxies et accès aux ressources qu'il peut localiser pendant l'exécution de votre application.
Remarque : il est important d'utiliser tous les chemins de code de votre application lors de l'exécution de l'agent de suivi afin de vous assurer que tous les cas de réflexion sont identifiés.
La documentation complète relative à l'agent de suivi est disponible ici.
Etape 5 : utilisation de l'agent de trace
A présent, utilisez l'agent de suivi pour générer la configuration de réflexion lors de l'exécution de votre application.
-
Exécutez l'application avec l'agent de suivi :
java -agentlib:native-image-agent=config-output-dir=./src/main/resources/META-INF/native-image -cp ./target/graalvmnidemos-1.0-SNAPSHOT-jar-with-dependencies.jar oracle.App
Examinez les fichiers de configuration créés par l'agent de suivi :
ls -l src/main/resources/META-INF/native-image/
Les éléments suivants doivent apparaître dans la sortie générée :
total 56 -rw-r--r-- 1 kfoster staff 4B Dec 2 19:13 jni-config.json -rw-r--r-- 1 kfoster staff 86B Nov 9 20:46 native-image.properties -rw-r--r-- 1 kfoster staff 65B Dec 2 19:13 predefined-classes-config.json -rw-r--r-- 1 kfoster staff 4B Dec 2 19:13 proxy-config.json -rw-r--r-- 1 kfoster staff 521B Dec 2 19:13 reflect-config.json -rw-r--r-- 1 kfoster staff 101B Dec 2 19:13 resource-config.json -rw-r--r-- 1 kfoster staff 4B Dec 2 19:13 serialization-config.json
Remarque : le projet contient un profil Maven qui peut effectuer cette opération pour vous. Exécutez la commande suivante pour utiliser l'agent de suivi :
mvn clean package exec:exec -Pjava_agent
-
Recréez maintenant le fichier exécutable. Cette fois, les fichiers de configuration produits par l'agent de suivi seront appliqués :
mvn package -Pnative
-
Enfin, exécutez le fichier généré :
time ./target/file-count
Le fichier exécutable fonctionne et génère des messages de journalisation dans la sortie, comme prévu.
Cela fonctionne car les fichiers générés par l'agent de suivi ont enregistré les classes référencées par réflexion. L'outil native-image
sait désormais qu'ils sont utilisés dans l'application et ne les exclut donc pas du fichier exécutable généré.
Remarque sur la position du paramètre -agentlib
Les paramètres d'agent doivent apparaître avant tout paramètre -jar
ou -classpath
. Vous devez également spécifier un répertoire dans lequel écrire les fichiers. L'emplacement recommandé est sous src/main/resources/META-INF/native-image
. Les fichiers placés à cet emplacement sont sélectionnés automatiquement par l'outil native-image
.
Remarque sur la configuration de la génération du fichier exécutable
Vous pouvez également transmettre des paramètres à l'outil native-image
à l'aide d'un fichier de propriétés Java (par défaut, src/main/resources/META-INF/native-image/native-image.properties
). Il existe un exemple de fichier dans le répertoire demo
pour vous donner une idée de ce que vous pouvez faire avec lui.
Conclusions
Dans cet atelier, vous avez testé plusieurs fonctionnalités GraalVM Native Image :
- Générer un fichier exécutable rapide à partir d'une application de ligne de commande Java
- Utilisation de Maven pour créer un fichier exécutable
- Comment utiliser l'agent de suivi pour automatiser le processus de suivi et d'enregistrement de la réflexion
Ecrivez des applications Java natives du cloud efficaces, plus sécurisées et évolutives et instantanément avec GraalVM Native Image !
En savoir plus
- Regardez une présentation de l'architecte Native Image Christian Wimmer GraalVM Native Image : analyse statique à grande échelle pour Java
- Documentation de référence sur GraalVM Native Image
Ressources de formation supplémentaires
Explorez d'autres exercices sur docs.oracle.com/learn ou accédez à davantage de contenu d'apprentissage gratuit sur le canal Oracle Learning YouTube. De plus, visitez le site education.oracle.com/learning-explorer pour devenir Oracle Learning Explorer.
Pour consulter la documentation du produit, consultez le centre d'aide Oracle.
GraalVM Native Image Quick Start
F51533-04
March 2022
Copyright © 2022, Oracle and/or its affiliates.