Introduction
The script command was introduced with SQLcl 4.2. It is based on JSR 223, the Java Scripting API, and makes it possible to run JavaScript from SQLcl. This adds client-side control flow, file access, better control of host commands and access to Java classes and JavaScript libraries.
JDK 8 was the latest and greatest back in 2015 when Kris Rice promoted this feature on his blog. The script command worked out of the box because JDK 8 included the Nashorn JavaScript engine. Nashorn was deprecated in JDK 11 and removed in JDK 15. The current version 26.2 of SQLcl requires JDK 11 or newer, but does not include a JavaScript engine. Therefore, script no longer works with a modern standard JDK.
The documented solution is to use GraalVM and install its JavaScript engine using the command gu install js. However, gu has been removed from more recent GraalVM distributions. Applications requiring a JavaScript engine must therefore provide the necessary Maven dependencies themselves.
Furthermore, the SQL Developer extension for VS Code comes with its own JDK 25. We cannot simply replace it with an older GraalVM JDK since some components require a JDK 25 and are therefore incompatible with older JDK versions.
The script command does not work in SQLcl embedded in SQL Developer for VS Code.
Let’s change that.
Patching SQLcl in SQL Developer for VS Code
I experimented with various approaches. The result is sqlcl-js-patch.sh. The idea is to download the missing JavaScript engine and its dependencies from Maven Central and add them to an SQLcl installation. This shell script supports GraalJS and Nashorn on JDK 17 and newer.
For SQL Developer for VS Code, I prefer Nashorn. It is compatible with the behaviour we had with JDK 8 and JDK 11 and produces no warnings when SQLcl starts.
Close all SQLcl sessions in VS Code. Then run the following command in a macOS, Linux or Git Bash shell:
curl --fail --location --silent --show-error \
https://raw.githubusercontent.com/PhilippSalvisberg/sqlcl-js-patch/refs/heads/main/sqlcl-js-patch.sh |
sh -s -- add nashorn "sqlcl_home=$HOME/.vscode"Downloading nashorn-core-15.7.jar
Downloading asm-7.3.1.jar
Downloading asm-commons-7.3.1.jar
Downloading asm-analysis-7.3.1.jar
Downloading asm-tree-7.3.1.jar
Downloading asm-util-7.3.1.jar
No matching libraries found in /Users/phs/.vscode/extensions/oracle.sql-developer-26.2.0-darwin-arm64/dbtools/sqlcl/lib.
Installed nashorn-core-15.7.jar
Installed asm-commons-7.3.1.jar
Installed asm-7.3.1.jar
Installed asm-analysis-7.3.1.jar
Installed asm-util-7.3.1.jar
Installed asm-tree-7.3.1.jar
No nashorn.args VM option found in macOS/Linux launcher; skipped Nashorn launcher patch.
Installed nashorn libraries in /Users/phs/.vscode/extensions/oracle.sql-developer-26.2.0-darwin-arm64/dbtools/sqlcl/lib.The patch script locates the most recent Oracle SQL Developer extension in the $HOME/.vscode/extensions directory. It adds the necessary JAR files to the embedded SQLcl, whose directory structure differs from that of standalone SQLcl.
Now start a new SQLcl session in VS Code and run:
script
print('Hello from Nashorn');
/SQLcl: Release 26.2 Production on Sat Jul 25 13:19:46 2026
Copyright (c) 1982, 2026, Oracle. All rights reserved.
Connected to:
Oracle AI Database 26ai Free Release 23.26.2.0.0 - Develop, Learn, and Run for Free
Version 23.26.2.0.0
Hello from Nashorn
SQL> This does not work when the code is executed directly in a SQL Developer worksheet. It works when you select Run in SQLcl.
That’s it. The script command is back.
Please note that updating the SQL Developer extension installs a new embedded SQLcl. In that case, run the patch command again.
Does It Work With GraalJS?
Yes.
Just pass graaljs instead of nashorn:
curl --fail --location --silent --show-error \
https://raw.githubusercontent.com/PhilippSalvisberg/sqlcl-js-patch/refs/heads/main/sqlcl-js-patch.sh |
sh -s -- add graaljs "sqlcl_home=$HOME/.vscode"Downloading collections-25.1.3.jar
Downloading icu4j-25.1.3.jar
Downloading jniutils-25.1.3.jar
Downloading js-language-25.1.3.jar
Downloading js-scriptengine-25.1.3.jar
Downloading nativeimage-25.1.3.jar
Downloading polyglot-25.1.3.jar
Downloading regex-25.1.3.jar
Downloading truffle-api-25.1.3.jar
Downloading truffle-compiler-25.1.3.jar
Downloading truffle-runtime-25.1.3.jar
Downloading word-25.1.3.jar
Downloading xz-25.1.3.jar
Deleted nashorn-core-15.7.jar
Deleted asm-commons-7.3.1.jar
Deleted asm-7.3.1.jar
Deleted asm-analysis-7.3.1.jar
Deleted asm-util-7.3.1.jar
Deleted asm-tree-7.3.1.jar
Deleted asm-commons-7.3.1.jar
Deleted asm-analysis-7.3.1.jar
Deleted asm-tree-7.3.1.jar
Deleted asm-util-7.3.1.jar
Installed collections-25.1.3.jar
Installed regex-25.1.3.jar
Installed truffle-compiler-25.1.3.jar
Installed polyglot-25.1.3.jar
Installed truffle-api-25.1.3.jar
Installed jniutils-25.1.3.jar
Installed truffle-runtime-25.1.3.jar
Installed js-language-25.1.3.jar
Installed xz-25.1.3.jar
Installed word-25.1.3.jar
Installed icu4j-25.1.3.jar
Installed js-scriptengine-25.1.3.jar
Installed nativeimage-25.1.3.jar
Installed graaljs libraries in /Users/phs/.vscode/extensions/oracle.sql-developer-26.2.0-darwin-arm64/dbtools/sqlcl/lib.Let’s start a new SQLcl session in VS Code and run:
script
print('Hello from GraalJS');
/Show/hide output
SQLcl: Release 26.2 Production on Sat Jul 25 12:20:22 2026
Copyright (c) 1982, 2026, Oracle. All rights reserved.
WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::load has been called by com.oracle.truffle.polyglot.JDKSupport in module org.graalvm.truffle (file:/Users/phs/.vscode/extensions/oracle.sql-developer-26.2.0-darwin-arm64/dbtools/sqlcl/lib/truffle-api-25.1.3.jar)
WARNING: Use --enable-native-access=org.graalvm.truffle to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
[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 engine uses a fallback runtime that does not support runtime compilation to native code.
Execution without runtime compilation will negatively impact the guest application performance.
The following cause was found: JVMCI is not enabled for this JVM. Enable JVMCI using -XX:+EnableJVMCI.
For more information see: https://www.graalvm.org/latest/reference-manual/embed-languages/#runtime-optimization-support.
To disable this warning use the '--engine.WarnInterpreterOnly=false' option or the '-Dpolyglot.engine.WarnInterpreterOnly=false' system property.
[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 engine uses a fallback runtime that does not support runtime compilation to native code.
Execution without runtime compilation will negatively impact the guest application performance.
The following cause was found: JVMCI is not enabled for this JVM. Enable JVMCI using -XX:+EnableJVMCI.
For more information see: https://www.graalvm.org/latest/reference-manual/embed-languages/#runtime-optimization-support.
To disable this warning use the '--engine.WarnInterpreterOnly=false' option or the '-Dpolyglot.engine.WarnInterpreterOnly=false' system property.
WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::objectFieldOffset has been called by com.oracle.truffle.api.strings.TStringUnsafe (file:/Users/phs/.vscode/extensions/oracle.sql-developer-26.2.0-darwin-arm64/dbtools/sqlcl/lib/truffle-api-25.1.3.jar)
WARNING: Please consider reporting this to the maintainers of class com.oracle.truffle.api.strings.TStringUnsafe
WARNING: sun.misc.Unsafe::objectFieldOffset will be removed in a future release
[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 engine uses a fallback runtime that does not support runtime compilation to native code.
Execution without runtime compilation will negatively impact the guest application performance.
The following cause was found: JVMCI is not enabled for this JVM. Enable JVMCI using -XX:+EnableJVMCI.
For more information see: https://www.graalvm.org/latest/reference-manual/embed-languages/#runtime-optimization-support.
To disable this warning use the '--engine.WarnInterpreterOnly=false' option or the '-Dpolyglot.engine.WarnInterpreterOnly=false' system property.
[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 engine uses a fallback runtime that does not support runtime compilation to native code.
Execution without runtime compilation will negatively impact the guest application performance.
The following cause was found: JVMCI is not enabled for this JVM. Enable JVMCI using -XX:+EnableJVMCI.
For more information see: https://www.graalvm.org/latest/reference-manual/embed-languages/#runtime-optimization-support.
To disable this warning use the '--engine.WarnInterpreterOnly=false' option or the '-Dpolyglot.engine.WarnInterpreterOnly=false' system property.
[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 engine uses a fallback runtime that does not support runtime compilation to native code.
Execution without runtime compilation will negatively impact the guest application performance.
The following cause was found: JVMCI is not enabled for this JVM. Enable JVMCI using -XX:+EnableJVMCI.
For more information see: https://www.graalvm.org/latest/reference-manual/embed-languages/#runtime-optimization-support.
To disable this warning use the '--engine.WarnInterpreterOnly=false' option or the '-Dpolyglot.engine.WarnInterpreterOnly=false' system property.
Connected to:
Oracle AI Database 26ai Free Release 23.26.2.0.0 - Develop, Learn, and Run for Free
Version 23.26.2.0.0
[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 engine uses a fallback runtime that does not support runtime compilation to native code.
Execution without runtime compilation will negatively impact the guest application performance.
The following cause was found: JVMCI is not enabled for this JVM. Enable JVMCI using -XX:+EnableJVMCI.
For more information see: https://www.graalvm.org/latest/reference-manual/embed-languages/#runtime-optimization-support.
To disable this warning use the '--engine.WarnInterpreterOnly=false' option or the '-Dpolyglot.engine.WarnInterpreterOnly=false' system property.
Hello from GraalJS
SQL> After several warnings, the expected result appears at the end.
I explained the GraalJS-related warnings in my GitHub repository. The following environment setting will suppress most of the warnings. Where you define this variable depends on your operating system and shell. In any case, the environment variable must be visible before you start VS Code.
export JDK_JAVA_OPTIONS="-Dpolyglot.engine.WarnInterpreterOnly=false -Dpolyglot.js.nashorn-compat=true"If you are only using JDK 24 or newer on your system, you can disable all warnings as follows. However, be aware that any JDK version below 24 will no longer work, because the Java runtime stops with an error when passing unknown JVM arguments.
export JDK_JAVA_OPTIONS="--illegal-native-access=allow --sun-misc-unsafe-memory-access=allow -Dpolyglot.engine.WarnInterpreterOnly=false -Dpolyglot.js.nashorn-compat=true"Can I Also Use This for Standalone SQLcl?
Yes.
Pass the SQLcl installation directory instead of the VS Code configuration directory:
curl --fail --location --silent --show-error \
https://raw.githubusercontent.com/PhilippSalvisberg/sqlcl-js-patch/refs/heads/main/sqlcl-js-patch.sh |
sh -s -- add nashorn "sqlcl_home=/path/to/sqlcl"This works very well on macOS and Linux. Besides installing the Nashorn libraries, the patch removes the following option from the bin/sql launcher:
-Dnashorn.args=--no-deprecation-warningThe standalone Nashorn engine does not support this option. It throws an exception while the engine is initialised, and SQLcl consequently reports JavaScript engine not found.
On Windows, bin/sql.exe is a binary executable. The patch script cannot modify it. It can add the Nashorn libraries when run from Git Bash, but it cannot apply the necessary launcher workaround. Therefore, Nashorn does not work with standalone SQLcl on Windows. GraalJS does not need this launcher change and is therefore the only option supported by the patch script on Windows:
curl --fail --location --silent --show-error \
https://raw.githubusercontent.com/PhilippSalvisberg/sqlcl-js-patch/refs/heads/main/sqlcl-js-patch.sh |
sh -s -- add graaljs "sqlcl_home=/path/to/sqlcl"This raises an interesting question. SQL Developer for VS Code also includes a Windows bin/sql.exe that the patch script cannot modify. So why does Nashorn work there?
But Why Does Nashorn Work in Embedded SQLcl?
I mentioned before that the embedded SQLcl version has a different folder structure (there is no lib/ext folder for third-party libraries). But that’s not the only difference.
The launcher is also different. Neither bin/sql nor bin/sql.exe includes the -Dnashorn.args=--no-deprecation-warning JVM option.
As a result, the Nashorn JavaScript engine works in the embedded SQLcl version of SQL Developer for VS Code.
Outlook
I hope this helps you bring the SQLcl script command back to life in your environments, especially in SQL Developer for VS Code, where using another Java runtime is not a practical option.
However, I also hope that we will not have to run sqlcl-js-patch.sh for every new SQLcl or SQL Developer extension version until the end of time. The patch consists mainly of adding libraries that are available from Maven Central. It would be great if the Oracle SQL Developer team included these libraries in a future update and made the script command work out of the box again.
