admin管理员组文章数量:1415139
There are several questions how to determine the javascript engine in browser. I have to write javascript code that has to run on rhino and nashorn.
How can I determine if my code is running on rhino or nashorn? Are there typcial functions, variables, constants where you can determine the engine?
There are several questions how to determine the javascript engine in browser. I have to write javascript code that has to run on rhino and nashorn.
How can I determine if my code is running on rhino or nashorn? Are there typcial functions, variables, constants where you can determine the engine?
Share Improve this question edited Jun 9, 2016 at 8:07 hippietrail 17.1k21 gold badges109 silver badges179 bronze badges asked Jun 9, 2016 at 6:46 Christian13467Christian13467 5,6341 gold badge32 silver badges34 bronze badges 4- 3 Interesting. Why do you need the check? – T.J. Crowder Commented Jun 9, 2016 at 6:49
- If you're asking about rhino vs nashorn, aren't you just asking about JDK SE 8 vs >8? – John Green Commented Jun 9, 2016 at 6:57
- @JohnGreen: "...about JDK SE 8 vs >8?" Nashorn was added in JDK8 (not >8). And it's still possible to run Rhino in JDK8 (but you have to add a jar and do it on purpose). – T.J. Crowder Commented Jun 9, 2016 at 7:05
- 1 We allow customers to setup there favorite engine. I just want to be shure what is set up, when no one can tell me, what they have done. – Christian13467 Commented Jun 9, 2016 at 8:25
3 Answers
Reset to default 1Looking at the Rhino to Nashorn migration guide, I see several possible ways.
If you're not using the Rhino patibility script, this would do it:
var usingNashorn = typeof importClass !== "function";
...since importClass
is defined for Rhino but not for Nashorn (unless you include the patibility script).
I think Java.type
is Nashorn-specific, so:
var usingNashorn = typeof Java !== "undefined" && Java && typeof Java.type === "function";
You could check for wrapping of exceptions:
var usingNashorn;
try {
// Anything that will throw an NPE from the Java layer
java.lang.System.loadLibrary(null);
} catch (e) {
// false!
usingNashorn = e instanceof java.lang.NullPointerException;
}
...since the migration guide says that will be true
for Nashorn but false
for Rhino. It does involve throwing an exception, which is unfortunate.
With --no-java option, "Java" is not defined as object in Nashorn. Best would be to check something that is available always in Nashorn. Something like DIR or FILE variable is a good candidate. Always there in nashorn.
jjs> typeof DIR
string
If you are using javax.script API (and not jjs), you can get the engine name and check as well:
import javax.script.*;
public class Main {
public static void main(String[] args) throws Exception {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByName("nashorn");
System.out.println(e.getFactory().getEngineName());
}
}
With Nashorn, you'd see "Oracle Nashorn" as the engine name.
I think the most robust and straightforward way to do this is to rely on the fact that both Rhino and Nashorn create per-thread execution contexts to do their work.
Nashorn's can be a bit more plicated to access because of the module (JPMS) changes introduced in Java 9, which makes it more difficult for scripts to access some of the classes involved.
Here's some code I use for this, in the SLIME codebase (which similarly supports both engines, and JDK 8/11 as of this writing). In each case, the engine provides a running
method that returns the engine-specific context if we are running inside that engine (so for simple detection, it could be wrapped inside a call to Boolean
or whatever). It is tested but as it's copy-paste out of context, it contains a bit of extraneous information, apologies for that:
Rhino (in this implementation you must call isPresent()
and ensure it returns true
before calling running()
, although you could improve that):
var rhino = (
function(global) {
return {
isPresent: function() {
return typeof(global.Packages.mozilla.javascript.Context.getCurrentContext) == "function";
},
running: function() {
return global.Packages.mozilla.javascript.Context.getCurrentContext();
}
}
}
)(this);
Nashorn (relies on Packages
, provided by the Mozilla patibility layer, mostly to improve static type-checking, but could easily be rewritten to use the Java
equivalents for Nashorn):
var nashorn = (
function() {
// TODO A little bit of this logic is duplicated in loader/jrunscript/nashorn.js; we could make this method
// available there somehow, perhaps, although it might be tricky getting things organized between
// bootstrapping Nashorn in the loader and loading the launcher bootstrap script
var Context = Packages.jdk.nashorn.internal.runtime.Context;
var $getContext;
if (typeof(Context) == "function") {
try {
// TODO is there any way to avoid repeating the class name?
$getContext = Packages.java.lang.Class.forName("jdk.nashorn.internal.runtime.Context").getMethod("getContext");
} catch (e) {
// do nothing; $getContext will remain undefined
}
}
var isPresent = function() {
if (!new Packages.javax.script.ScriptEngineManager().getEngineByName("nashorn")) {
$api.debug("Nashorn not detected via javax.script; removing.");
return false;
}
if (typeof(Context.getContext) != "function" && !$getContext) {
$api.debug("jdk.nashorn.internal.runtime.Context.getContext not accessible; removing Nashorn.")
return false;
}
return true;
}
return {
isPresent: isPresent,
running: function() {
if ($getContext) {
try {
return $getContext.invoke(null);
} catch (e) {
return null;
}
} else {
return null;
}
}
}
}
)();
Sure, the Nashorn implementation uses non-public APIs. But I still think this is better, and more straightforward, than relying on what are essentially side effects (existence of various cherry-picked APIs that one or the other engine might provide). These techniques are potentially breakable if either engine seeks to improve patibility with the other.
本文标签: How can I determine which javascript enginerhino or nashorn is running my codeStack Overflow
版权声明:本文标题:How can I determine which javascript engine, rhino or nashorn is running my code? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745229608a2648764.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论