I have version 21 installed and as far as I understand, I can't use Nashorn engine anymore, but maybe GraalVM is available for me?
I have installed all the necessary dependencies:
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>21.1.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>21.1.0</version>
</dependency>
Here is a simple example that I'm trying to execute:
public static void main(String[] args) throws ScriptException {
try (Context context = Context.newBuilder("js")
.allowAllAccess(true)
.build()) {
// Evaluate JavaScript code
String jsCode = "console.log('Hello, GraalVM!');";
context.eval("js", jsCode);
} catch (Exception e) {
throw new ScriptException("Script execution failed: " + e.getMessage());
}
}
However, I get an error:
Exception in thread "main" javax.script.ScriptException: Script execution failed: A language with id 'js' is not installed. Installed languages are: []. at org.example.Main.main(Main.java:23)
I also tried something like this:
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
engine.eval("print('HI');");
}
But I got another error:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null at org.example.Main.main(Main.java:20)
The problem is that manual installation of any components is impossible for some reason. I just need to some dependencies and make everything works. Something "out of the box". Is there any workaround for this problem? Maybe there are any other available engines?
jsEngineScriptJDK21_graalvm_js
├── pom.xml
└── src
└── main
└── java
└── com
└── example
└── JsTest.java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>graalvm-js-engine-script</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>GraalvmJsEngineScript</name>
<description>jsEngineScript App Project</description>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>23.0.0</version>
</dependency>
</dependencies>
<build>
<finalName>app</finalName>
</build>
</project>
package com.example;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
public class JsTest {
public static void main(String[] args) throws Exception {
try (Context context = Context.newBuilder("js")
.allowAllAccess(true)
.build()) {
// Evaluate JavaScript code
String jsCode = "console.log('Hello, GraalVM!');";
context.eval("js", jsCode);
} catch (Exception e) {
throw new Exception("Script execution failed: " + e.getMessage());
}
}
}
package com.example;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
public class JsTest3 {
public static void main(String[] args) throws Exception {
try (Context context = Context.newBuilder("js")
.option("engine.WarnInterpreterOnly", "false")
.allowAllAccess(true)
.build()) {
Value result = context.eval("js", "2 + 2");
System.out.println("Result: " + result.asInt());
// Call JavaScript Function
context.eval("js", "function greet(name) { return 'Hello, ' + name; }");
Value greetFunction = context.getBindings("js").getMember("greet");
System.out.println("Greeting: " + greetFunction.execute("World").asString());
// Evaluate JavaScript code
String jsCode = "print('HI');";
context.eval("js", jsCode);
} catch (Exception e) {
throw new Exception("Script execution failed: " + e.getMessage());
}
}
}
mvn clean package
mvn dependency:copy-dependencies -DoutputDirectory=target/libs
java -cp "target/libs/*:target/app.jar" \
com.example.JsTest
Result:
[To redirect Truffle log output to a file use one of the following options:
* '--log.file=<path>' if the option is passed using a guest language launcher.
* '-Dpolyglot.log.file=<path>' if the option is passed using the host Java launcher.
* Configure logging using the polyglot embedding API.]
[engine] WARNING: The polyglot context is using an implementation that does not support runtime compilation.
The guest application code will therefore be executed in interpreted mode only.
Execution only in interpreted mode will strongly impact the guest application performance.
For more information on using GraalVM see https://www.graalvm.org/java/quickstart/.
To disable this warning the '--engine.WarnInterpreterOnly=false' option or use the '-Dpolyglot.engine.WarnInterpreterOnly=false' system property.
Hello, GraalVM!
java -cp "target/libs/*:target/app.jar" \
com.example.JsTest3
Result: There is no warning message.
Result: 4
Greeting: Hello, World
HI
$ javac -version
javac 21.0.4
$ java -version
openjdk version "21.0.4" 2024-07-16 LTS
OpenJDK Runtime Environment Temurin-21.0.4+7 (build 21.0.4+7-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.4+7 (build 21.0.4+7-LTS, mixed mode, sharing)
Notice:
mvn clean package
. If no error occurs, it is a problem with the IDE.jsEngineScriptJDK21
├── pom.xml
└── src
└── main
└── java
└── com
└── example
└── JsTest.java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>js-engine-script</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jsEngineScript</name>
<description>jsEngineScript App Project</description>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<version>15.4</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>app</finalName>
</build>
</project>
package com.example;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class JsTest {
public static void main(String[] args) throws ScriptException {
try {
//ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
//ScriptEngine engine =new ScriptEngineManager().getEngineByName("JavaScript");
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
if (engine == null) {
System.out.println("Nashorn script engine not available.");
return;
}
engine.eval("print('HI');");
engine.eval("print('Hello, Nashorn!');");
engine.eval("var x = 10 + 20; print('x = ' + x);");
} catch (ScriptException e) {
e.printStackTrace();
}
}
}
mvn clean package
mvn dependency:copy-dependencies -DoutputDirectory=target/libs
java -cp "target/libs/*:target/app.jar" \
com.example.JsTest
Result:
HI
Hello, Nashorn!
x = 30