Skip to content

Instantly share code, notes, and snippets.

@vivin
Created December 8, 2015 22:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vivin/2e20c21f6fecf416474f to your computer and use it in GitHub Desktop.
Save vivin/2e20c21f6fecf416474f to your computer and use it in GitHub Desktop.
Accessing raw global objects in nashorn

Did this while I was figuring out how to share global objects across isolated contexts. Kinda works, but not really. Prototypes are broken because the internal Global object maintains the original instance. So even after overwriting, something like Object.getPrototypeOf({}) === Object.prototype returns false... which was what I was trying to get around originally, anyway. sigh

Map<String, Object> nativeJavaScriptObjects = new HashMap<>();
try {
    engine.getBindings(ScriptContext.ENGINE_SCOPE).put("globals", (BiConsumer<String, Object>) (s, o) ->
        nativeJavaScriptObjects.put(s, ScriptUtils.unwrap(o))
    );
    engine.eval("Object.getOwnPropertyNames(this).forEach(function(n) { if(Object.getOwnPropertyDescriptor(this, n).writable && n !== 'globals' && n !== 'javax.script.filename') { globals(n, this[n]); } }, this)");
    engine.getBindings(ScriptContext.ENGINE_SCOPE).remove("globals");
} catch(Exception e) {
    throw new RuntimeException(e);
}

//later:
nativeJavaScriptObjects.forEach((name, nativeObject) -> {
    try {
        newContext.setAttribute("_" + name, nativeObject, ScriptContext.ENGINE_SCOPE);
        this.engine.eval("this." + name + " = _" + name + ";", newContext);
        newContext.removeAttribute("_" + name, ScriptContext.ENGINE_SCOPE);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
});

The reason this works is that calling a Java method that takes in parameters of type Object from JavaScript supposedly doesn't wrap the object in ScriptObjectMirror. I didn't find this to be the case, but I did notice that calling ScriptUtils.unwrap actually did unwrap the object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment