GraalVM, une machine virtuelle polyglotte qui fournit un runtime partagé pour exécuter des applications écrites dans plusieurs langages comme Java, Python et JavaScript a publié la version majeure 20.0 avec une prise en charge complète sur la plate-forme Windows. La distribution Windows GraalVM 20.0 inclut désormais le moteur JavaScript, l'utilitaire de mise à jour GraalVM gu
et le JDK avec le compilateur GraalVM activé. Notez que contrairement aux distributions Linux et MacOS, la prise en charge de Node.js n'est pas encore disponible sur Windows.
L'utilitaire de génération d'images natives de GraalVM a également été mis à jour pour fournir une prise en charge étendue sur Windows. Une image native est un bytecode Java compilé de type ahead-of-time en tant qu'exécutable autonome. L'image native permet généralement un temps de démarrage plus rapide et une empreinte mémoire réduite. L'utilitaire d'images natives doit être installé à l'aide de l'utilitaire de mise à jour GraalVM gu
. gu
est un gestionnaire de packages qui télécharge et installe des packages non inclus dans la distribution principale de GraalVM.
Dans une autre news, Apache Tomcat 9 a annoncé un support complet pour les images natives GraalVM qui incluent le conteneur. Cependant, des précautions doivent être prises lors de la création d'images natives basées sur Tomcat, car d'autres bibliothèques tierces utilisées par les applications Web Tomcat peuvent ne pas prendre entièrement en charge les images natives. Par exemple, si une bibliothèque dépend du chargement de classe dynamique ou de la réflexion, la VM Substrat de GraalVM doit d'abord être exécutée à l'aide du tracing agent afin de générer automatiquement les fichiers de configuration utilisés par l'image native. Ces fichiers peuvent être placés dans META-INF/native-image
de l'application Web ou du jar pour prendre en charge des fonctionnalités telles que la réflexion à l'intérieur de l'image native.
L'exemple de code suivant présente une classe Java 11 simple qui exécute un serveur Tomcat embarqué :
public class TED {
public static void main(String... args)
throws Exception {
File baseFolder = new File(System.getProperty("user.dir"));
File appsFolder = new File(baseFolder, "web-apps");
var tomcat = new Tomcat();
tomcat.setBaseDir(baseFolder.getAbsolutePath());
tomcat.setPort(8080);
tomcat.getHost().setAppBase(appsFolder.getAbsolutePath());
// Call the connector to create the default connector.
tomcat.getConnector();
tomcat.addWebapp("", appsFolder.getAbsolutePath());
var wrapper = tomcat.addServlet("", "hello", new HelloServlet());
wrapper.setLoadOnStartup(1);
wrapper.addMapping("/*");
tomcat.start();
tomcat.getServer().await();
}
private static class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setStatus(200);
var writer = resp.getWriter();
writer.write("Hello from Tomcat native image!");
writer.flush();
writer.close();
}
}
}
Utilisez le plug-in Maven Shade ou le plug-in Gradle Shadow pour compiler et construire la classe dans un uber JAR car l'utilitaire native-image
est plus facile à utiliser avec un JAR unique. Une fois l'uber JAR créé, exécutez le tracing agent de GraalVM pour générer des fichiers de configuration pour l'image native. L'extrait de code suivant montre comment exécuter le tracing agent de GraalVM pour générer des fichiers de configuration pour la réflexion, JNI (Java Native Interface), des ressources du classpath et des proxys dynamiques :
java \
-agentlib:native-image-agent=config-merge-dir=graal-conf \
-cp build/libs/ted-1.0-all.jar my.example.TED
L'agent de suivi crée les différents fichiers de configuration en JSON qui peuvent être transmis à l'utilitaire native-image
:
native-image --no-server \
-cp build/libs/ted-0.0.1-SNAPSHOT-all.jar \
--allow-incomplete-classpath \
-H:+JNI -H:+ReportUnsupportedElementsAtRuntime \
-H:+ReportExceptionStackTraces -H:EnableURLProtocols=http,jar,jrt \
-H:ConfigurationFileDirectories=graal-conf/ \
-H:ReflectionConfigurationFiles=graal-conf/reflect-config.json \
-H:ResourceConfigurationFiles=graal-conf/resource-config.json \
-H:JNIConfigurationFiles=graal-conf/jni-config.json \
my.example.TED ted
Dans l'exemple ci-dessus, l'utilitaire crée un binaire natif ted
avec une taille de fichier d'environ 40 Mo. Il peut être exécuté sans JDK ou JRE installé :
./ted
Accédez à l'url http://localhost:8080
et vous serez accueilli avec un message de bienvenue tel que défini dans l'exemple de la classe Java :
Notez que plusieurs fonctionnalités utilisées par Tomcat comme la sérialisation Java, JMX, JULI et la liaison statique de tomcat-native ne sont pas encore prises en charge dans l'image native GraalVM.
Outre les améliorations des images natives et la prise en charge de Windows, l'implémentation de GraalVM de WebAssembly language, GraalWasm, est désormais disponible en tant que fonctionnalité expérimentale. À l'aide de l'API polyglotte, les webassembly peuvent être intégrées et exécutées à partir d'applications Java.
Une autre modification notable de Java dans GraalVM est que le paramètre par défaut pour ThreadPriorityPolicy
est défini sur 1. Cela signifie que les priorités de thread définies dans Java sont reflétées par les priorités de thread du système d'exploitation natif. Des précautions doivent être prises lors de la migration des applications sensibles aux performances, car le ThreadPriorityPolicy
par défaut peut affecter les performances des applications.
Cette version de GraalVM a corrigé plusieurs problèmes JNI et JDK 11 liés à la génération d'images natives. Un nouveau visualiseur de données du JDK Flight Recorder a été ajouté à GraalVM VisualVM, une version améliorée de VisualVM. Les temps d'exécution de NodeJS, Ruby et LLVM ont également été amélioré. Une preview de la technologie Language Server Protocol pour les langues GraalVM est disponible dans GraalVM VSCode Extensions.
Les distributions de GraalVM basées sur JDK 8 et JDK 11 peuvent être téléchargées à partir de GitHub.