- Loading...
...
| Code Block | ||
|---|---|---|
| ||
// can load script from files, URLs
load("foo.js"); // loads script from file "foo.js" from current directory
load("http://www.example.com/t.js"); // loads script file from given URL
// loads script from an object's properties.
// Object should have "script" and "name" properties.
// "script" property contains string code of the script.
// "name" property specifies name to be used while reporting errors from script
// This is almost like the standard "eval" except that it associates a name with
// the script string for debugging purpose.
load({ script: "print('hello')", name: "myscript.js"})
// load can also load from pseudo URLs like "nashorn:", "fx:"., "classpath:"
// "nashorn:" pseudo URL scheme
// for nashorn's built-in scripts. "fx:" pseudo URL scheme for JavaFX support scripts
// load nashorn's parser support script - defines 'parse'
// function in global scope
load("nashorn:parser.js");
// load Mozilla compatibility script - which defines global functions
// like importPackage, importClass for rhino compatibility.
load("nashorn:mozilla_compat.js");
// "fx:" pseudo URL scheme for JavaFX support scripts
// "classpath:" pseudo URL scheme to load scripts from jjs classpath jars and directories
load("classpath:foo.js"); // load the first foo.js found in jjs -classpath dir |
Anchor loadWithNewGlobal loadWithNewGlobal
...
| Code Block | ||
|---|---|---|
| ||
#// Usage: jjs -fx filebrowser.js -- <start_dir>
// Uses -fx and javafx TreeView to visualize directories
if (!$OPTIONS._fx) {
print("Usage: jjs -fx filebrowser.js -- <start_dir>");
exit(1);
}
// Java classes used
var File = Java.type("java.io.File");
var Files = Java.type("java.nio.file.Files");
// check directory argument, if passed
var dir = arguments.length > 0? new File(arguments[0]) : new File(".");
if (! dir.isDirectory()) {
print(dir + " is not a directory!");
exit(2);
}
// JavaFX classes used
var FXCollections = Java.type("javafx.collections.FXCollections");
var Scene = Java.type("javafx.scene.Scene");
var TreeItem = Java.type("javafx.scene.control.TreeItem");
var TreeView = Java.type("javafx.scene.control.TreeView");
// create a subclass of JavaFX TreeItem class
var LazyTreeItem = Java.extend(TreeItem);
// lazily filling children of a directory LazyTreeItem
function buildChildren(dir) {
var children = FXCollections.observableArrayList();
var stream = Files.list(dir.toPath());
stream.forEach(function(path) {
var file = path.toFile();
var item = file.isDirectory()?
makeLazyTreeItem(file) : new TreeItem(file.name);
children.add(item);
});
stream.close();
return children;
}
// create an instance LazyTreeItem with override methods
function makeLazyTreeItem(dir) {
var item = new LazyTreeItem(dir.name) {
expanded: false,
isLeaf: function() false,
getChildren: function() {
if (! this.expanded) {
// call super class (TreeItem) method
Java.super(item).getChildren().setAll(buildChildren(dir));
this.expanded = true;
}
// call super class (TreeItem) method
return Java.super(item).getChildren();
}
}
return item;
}
// JavaFX start method
function start(stage) {
stage.title = dir.absolutePath;
var rootItem = makeLazyTreeItem(dir);
rootItem.expanded = true;
var tree = new TreeView(rootItem);
stage.scene = new Scene(tree, 300, 450);
stage.show();
} |
...
Anchor Java_synchronized Java_synchronized
Java.synchronized function
Returns synchronized wrapper version of the given ECMAScript function.
| Code Block | ||||
|---|---|---|---|---|
| ||||
var Thread = Java.type("java.lang.Thread");
var sum = 0;
var lock = {};
function run() {
Thread.sleep(Math.floor(Math.random()*700) + 300);
// create synchronized wrapper of given function
// and use the second param as the synchronization lock
Java.synchronized(function() sum++, lock)();
}
var threads = [];
for (var i = 0; i < 4; i++) {
var t = new Thread(run);
threads.push(t);
t.start();
}
for (var i in threads) {
threads[i].join();
}
// always prints 4
print(sum); |
Anchor Java.asJSONCompatible Java.asJSONCompatible
Java.asJSONCompatible function
This function accepts a script object and returns an object that is compatible with Java JSON libraries expectations; namely, that if it itself, or any object transitively reachable through it is a JavaScript array,then such objects will be exposed as JSObject that also implements the List interface for exposing the array elements.
An explicit API is required as otherwise Nashorn exposes all objects externally as JSObjects that also implement the Map interface instead. By using this method, arrays will be exposed as Lists and all other objects as Maps.
This API is since jdk 8u60+ and jdk 9. A simple example that uses Java.asJSONCompatible function:
| Code Block | ||||
|---|---|---|---|---|
| ||||
import javax.script.*;
import java.util.*;
public class JSONTest {
public static void main(String[] args) throws Exception {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByName("nashorn");
Object obj = e.eval("Java.asJSONCompatible({ x: 343, y: 'hello', z: [2,4, 5] })");
Map<String, Object> map = (Map<String, Object>)obj;
System.out.println(map.get("x"));
List<Object> array = (List<Object>)map.get("z");
for (Object elem : array) {
System.out.println(elem);
}
}
} |
| Anchor | ||||
|---|---|---|---|---|
|
...
| Code Block | ||
|---|---|---|
| ||
var HashMap = Java.type("java.util.HashMap")
var map = new HashMap()
// map key-value access by java get/put method calls
map.put('js', 'nashorn')
print(map.get('js'))
// access keys of map as properties
print(map['js'])
print(map.js)
// also assign new key-value pair
// as 'property-value'
map['language'] = 'java'
print(map.get("language"))
print(map.language)
print(map['language'])
map.answer = 42
print(map.get("answer"))
print(map.answer)
print(map['answer']) |
| Anchor | ||||
|---|---|---|---|---|
|
...
Explicit constructor selection (jdk9, jdk8u65)
With jdk9 and jdk8u65, explicit constructor overload selection is also supported. See Index selection of overloaded java new constructors and Explicit constructor overload selection should work with StaticClass as well
| Code Block | ||
|---|---|---|
| ||
// With jdk9, you can select a specific constructor as well.
var C = java.awt["Color(int,int,int)"];
print(new C(255, 0, 0);
var F = Java.type("java.io.File")["(String)"];
print(new F("foo.txt"));
|
...
If the command does not require any input, you can launch a process using the backtick string notation. For example, instead of $EXEC("ls -l"), you can use `ls -l`.
$OUT (-scripting mode only)
This global object is used to store the latest standard output (stdout) of the process spawned by $EXEC. For example, the result of $EXEC() is saved to $OUT.
use `ls -l`.
$OUT $ERR (-scripting mode only)
This global object is used to store the latest standard error output (stderrstdout) of the process spawned by $EXEC.
$EXIT (-scripting mode only)
This global object is used to store the exit code of the process spawned by $EXEC. If the exit code is not zero, then the process failedFor example, the result of $EXEC() is saved to $OUT.
| Code Block | ||
|---|---|---|
| ||
var Arrays = Java.type("java.util.Arrays") // use curl to download JSON weather data from the net var str = `curl http://api.openweathermap.org/data/2.5/forecast/daily?q=Chennai&mode=json&units=metric&cnt=7` // parse JSON var weather = JSON.parse($OUT) // pull out humidity as array var humidity = weather.list.map(function(curVal) { return curVal.humidity }) // Stream API to print stat print("Humidity") print(Arrays["stream(int[])"](humidity).summaryStatistics()) // pull maximum day time temperature var temp = weather.list.map(function(curVal) { return curVal.temp.max }) // Stream API to print stat print("Max Temperature") print(Arrays["stream(double[])"](temp).summaryStatistics()) |
$ERR (-scripting mode only)
This global object is used to store the latest standard error (stderr) of the process spawned by $EXEC.
$EXIT (-scripting mode only)
This global object is used to store the exit code of the process spawned by $EXEC. If the exit code is not zero, then the process failed
$OPTIONS (-scripting mode only)
...
profiling is enabled per script or per function only rather than globally. These nashorn directives are enabled only in nashorn debug mode. So, these are effective only when jjs is run -J-Dnashorn.debug option set or script engine is initialized after "nashorn.debug" system property is set to true. Also, this feature is available only on jdk 8u40 + and jdk 9 only.