22 votes

Comment utiliser Nashorn dans Java 15 et plus ?

J'ai une application Spring Boot existante qui n'est pas modulaire et qui utilise Nashorn. L'application fonctionne bien sur Java 14.

Après avoir ajouté les coordonnées Maven du nouveau Nashorn disponible pour Java 15, l'application échoue lors du démarrage du moteur script.

public static void main(String[] args) throws ScriptException {
    ScriptEngineManager factory = new ScriptEngineManager();
    ScriptEngine engine = factory.getEngineByName("nashorn"); 
    engine.eval("print('Hello, World!');");
} 

Message d'erreur :

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null
    at xxxxx.yyyy.service.JavaScriptServiceImpl.main(JavaScriptServiceImpl.java:52)

Est-il nécessaire de modulariser l'ensemble du projet pour utiliser Nashorn ?

18voto

MK Tan Points 506

Selon JEP 372 Nashorn a été supprimé du JDK 15, mais vous pouvez obtenir la dernière version de Nashorn à l'adresse suivante https://search.maven.org/artifact/org.openjdk.nashorn/nashorn-core/15.0/jar

Pour Maven, incluez la dépendance ci-dessous dans votre fichier pom.xml

<dependency>
  <groupId>org.openjdk.nashorn</groupId>
  <artifactId>nashorn-core</artifactId>
  <version>15.0</version>
</dependency>

Pour Gradle, inclure la dépendance ci-dessous dans votre build.gradle

implementation 'org.openjdk.nashorn:nashorn-core:15.0'

Malheureusement, Standalone Nashorn est uniquement utilisable en tant que module JPMS. Vous devrez donc peut-être suivre la solution indiquée dans https://stackoverflow.com/a/46289257 pour le faire fonctionner avec une application non modulaire.

De la classe donnée xxxxx.yyyy.service.JavaScriptServiceImpl et d'après les commentaires de @JornVernee et @AttilaSzegedi, la ligne de commande devrait ressembler à ceci

jdk-15.0.1/bin/java -classpath /home/nashorn-helloworld/target/classes --module-path /home/org/openjdk/nashorn/nashorn-core/15.0:/home/org/ow2/asm/asm/7.3.1:/home/org/ow2/asm/asm-analysis/7.3.1:/home/org/ow2/asm/asm-commons/7.3.1:/home/org/ow2/asm/asm-tree/7.3.1/home/org/ow2/asm/asm-util/7.3.1 --add-modules org.openjdk.nashorn xxxxx.yyyy.service.JavaScriptServiceImpl

17voto

Attila Szegedi Points 478

Je viens de publier Nashorn 15.1 qui permet à Nashorn de fonctionner lorsqu'il est chargé via classpath au lieu de modulepath. Je l'ai testé avec une petite application Spring Boot de mon cru, et cela fonctionne.

15voto

Attila Szegedi Points 478

Ici le mainteneur de Nashorn.

Il semble en effet que Spring Boot ne charge pas Nashorn comme un module JPMS. Nashorn s'exporte en tant que moteur de script pour être trouvé par le module JPMS. javax.script.ScriptEngineManager par le biais d'un "fournit" dans son module-info.java . Il n'utilise pas l'ancien mécanisme d'exportation, non modulaire, qui consiste à se déclarer par le biais d'un fichier d'exportation pertinent. META-INF/services/… dans son fichier JAR. Cela signifie que si le JAR n'est pas chargé comme un module JPMS, le gestionnaire du moteur script sera no le découvrir. (NB : même s'il avait de manière redondante cette META-INF/services l'entrée, cela n'aiderait pas car Nashorn repose sur le fait d'être chargé en tant que module ; en tant que code qui était livré avec le JDK, il est un module depuis Java 9 il serait quelque peu difficile de défaire cela maintenant).

J'ai créé un petite application de test qui confirme que c'est le cas. J'essaie de faire appel à des personnes qui travaillent sur Boot pour m'aider à faire la lumière sur cette affaire. C'est compliqué par le fait que Boot crée un gros fichier JAR et y emballe toutes ses dépendances, puis gère leur chargement, donc ce n'est pas comme si vous pouviez "simplement" modifier le modulepath vous-même au démarrage.

J'espère qu'il existe un moyen d'indiquer à Boot de charger une dépendance en tant que module ; mes tentatives de recherche sur Google n'ont pas porté leurs fruits jusqu'à présent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X