Tutoriel JShell: Script et scripts de démarrage

JShell aborde des aspects avancés de l’utilisations de cet outil. On y traitera les sujets de la création de scripts Java avec JShell et celui des scripts de démarrage. Ce tutoriel fait partie d’une serie de quatre articles qui permettront de se familiariser, suffisament, avec JShell afin de pouvoir l’utiliser efficacement et augmenter la productivité avec le langage de programmation Java:

  1. Tutoriel JShell: Installation et concepts
  2. Tutoriel JShell: Utilisation
  3. Cet article: Tutoriel JShell: Scripts et scripts de démarrage
  4. Tutoriel JShell: Personnalisation et Import de librairies externes

1. Scripts JShell

Lancer JShell et exécuter les trois instructions Java suivantes, l’une après l’autre dans l’ordre indiqué:
char c = 'D'
int rang = (int)c - 64
System.out.printf("D est la lettre de rang %d dans l'alphabet\n", rang)
Comme attendu, à chaque fois JShell répond immédiatement pour donner le résultat de l’instruction. Maintenant on peut visualiser l’ensemble de ces instructions par:
/list
On obtient une liste numérotée de l’historique des instructions exécutées depuis le début de la session (remarquer l’ajout automatique des points-virgules à la fin des lignes):
   1 : char c = 'D';
   2 : int rang = (int)c - 64;
   3 : System.out.printf("D est la lettre de rang %d dans l'alphabet\n", rang);
Il est possible de sauvegarder cette suite d’instructions Java dans un fichier pour constituer un script JShell:
/save premierscript.jsh
Pour vérifier le succés de l’opération, quitter Jshell (commande /exit) et visualiser le contenu du fichier de script fraîchement créé:
cat premierscript.jsh
Bien entendu on aurait pu, également, créer ce script directement avec un éditeur de texte. Maintenant qu’on a ce fichier de script on peut l’exécuter à partir du Shell système par:
jshell premierscript.jsh
Cette commande donne le résultat:
D est la lettre de rang 4 dans l'alphabet
|  Welcome to JShell -- Version 10.0.2
|  For an introduction type: /help intro
jshell>_
La première ligne de la réponse montre bien que le script a été exécuté. Le problème est qu’on se trouve à la fin dans l’environnement de l’outil. Ce comportement n’est souvent pas souhaitable. Pour remedier à cet inconvénient, on doit modifier le contenu du script. Quitter JShell, éditer le fichier premierscript.jsh pour y ajouter à la fin la commande JShell: /exit. Avec cette nouvelle version du script, on retournera au Shell système à la fin de l’exécution. Deux enseignements sont à retenir de cette manipulation:
  1. On doit ajouter la commande /exit à la fin d’un script si on souhaite se retrouver dans le Shell système à la fin de son exécutionn, ce qui est souvent le cas.
  2. On peut combiner des instructions Java et des commandes JShell dans un script JShell.

2. Scripts de démarrage

Un script de démarrage JShell est un script tel qu’on vient de le voir dans le paragraphe précédent qui est exécuté automatiquement par l’environnement de l’outil dans les deux cas suivant:
  1. Au démarrage de l’environnement en utilisant le paramètre –startup <NomDuScript>
  2. A l’exécution de l’une des commandes: /env, /reset et /reload
Ce comportement est utile pour paramétrer à souhait JShell. Il existe trois scripts de démarrage prédéfinis qui peuvent assurer un paramétrage minimal:
  1. DEFAULT : exécuté par défaut, même si on ne l’invoque pas. C’est à dire même si on n’utilise pas le paramètre –startup pour lancer JShell.
  2. PRINTING : Assure un paramétrage qui facilite l’affichage des données
  3. JAVASE : Permet d’utiliser toutes les librairies de Java SE
Pour s’en rendre compte, exécuter:
jshell --startup PRINTING
Cette commande, lance JShell avec le script de démarrage prédéfini PRINTING (au lieu de DEFAULT donc). Exécuter ensuite:
printf("Le nombre %d est le double du chiffre %d", 10, 5)
Cette instruction n’est pas conforme à la syntaxe Java, pourtant elle s’exécute sans erreur. Pour illucider ce mystère, exécuter dans l’ordre:
/reset
/open PRINTING
/list
La première comande permet de remettre l’environnement à zéro. La seconde permet de charger le script PRINTING. La troisième liste le contenu de ce script. On se rend compte, grâce à ces commandes, que le script PRINTING définit une série de méthodes qui servent toutes à l’affichage de données dont la méthode utilisé printf(…). Ceci explique l’exécution sans erreur de cette instruction. Quitter JShell et relancer le sans aucun paramètre:
jshell
|  Welcome to JShell -- Version 10.0.2
|  For an introduction type: /help intro

jshell>_
Exécuter maintenant:
printf("Le nombre %d est le double du chiffre %d", 10, 5)
On obtient le message d’erreur:
|  Error:
|  cannot find symbol
|    symbol:   method printf(java.lang.String,int,int)
|  printf("Le nombre %d est le double du chiffre %d", 10, 5)
|  ^----^
Ce qui est tout à fait normal puisque cette fois c’est DEFAULT qui s’est exécuté au démarrage et il ne contient pas la définition de cette méthode. Vérifions:
/reset
/open DEFAULT
/list
Le script DEFAULT se contente d’importer un nombre limité de packages du JRE. On peut conclure que par défaut on ne peut utiliser que ces packages (en plus de java.lang.* qui est utilisable sans besoin de l’importer) dans l’environnement JShell.

3. Scripts de démarrage personnalisés

De même qu’avec les scripts prédéfinis, on peut utiliser un script personnalisé pour le démarrage de JShell. Généralement, le script de démarrage sert à configurer l’environnement pour mieux l’utiliser: import de packages, référencement de modules, définitions de méthodes.. Lancer JShell sans aucun paramètre. Dans ces conditions, c’est le script de démarrage par défaut qui sera utilisé. Ensuite, exécuter l’instruction Java suivante, qui permet de déterminer si un site web répond correctement en renvoyant le statut HTTP d’une requête GET:
HttpClient.newHttpClient().send(HttpRequest.newBuilder().uri(new URI("http://www.meddeb.net")).build(), HttpResponse.BodyHandler.asString()).statusCode()
L’exécution de l’instruction échoue. La raison de cet echec est l’utilisation de classes Java qui font partie d’un module et de packages non visibles dans l’environnement JShell. De plus, aucun des 3 scripts prédéfinis ne permet d’importer les pré-requis nécessaires à cette exécution. A l’aide d’un éditeur de texte crééer un ficher de script personnalisé http.jsh, dont le contenu est:
/env --add-modules jdk.incubator.httpclient
import jdk.incubator.http.*
import java.net.*
Lancer JShell avec ce script de démarrage personnalisé:
jshell --startup http.jsc
Maintenant JShell est configuré convenablement pour exécuter la commande précédente qui a échoué. Relancer cette commande. Si le site fonctionne normalement au moment de l’exécution, la réponse sera égale à 200, le code qui correspond à un statut « Tout va bien ».]]>