在开发Android应用程序时是否可以引用javax.script.ScriptEngine库?如果没有,那么有可能在android中评估一个javascript表达式?
我开始使用ScriptEngine来运行javascript代码.我发现它非常有用并且对我的需求有益,但有一件事是缺失的,它的调试.我该怎么做?我真的希望能够只是放一个断点或步入,看看js解释器一步一步地运行我的代码.那可能吗?
我对Nashorn很新,并且在JVM之上编写脚本,并想知道我是否可以让我的java代码和javascripts更有效地进行通信.
我正在使用与JS对象一起使用的第三方JS库,在我的java代码中,我有想要传递的数据Map<String, Object> data.
因为第三方JS希望使用普通的JS对象,所以我无法data按原样传递,尽管脚本引擎允许您访问Map,就像它是一个普通的JS对象一样.
我正在使用的脚本在data参数上使用'hasOwnProperty',并且在Java对象上调用时失败.
当我尝试使用Object.prototype.hasOwnProperty.call(data,'myProp')时,它也不起作用并且总是返回'false'.基本问题是Java Object不是javascript对象原型.
我最终做了这样的事情:
Map<String, Object> data;
ObjectMapper mapper = new ObjectMapper();
String rawJSON = mapper.writeValueAsString(data);
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval('third_party_lib.js');
engine.eval('function doSomething(jsonStr) { var jsObj = JSON.parse(jsonStr); return doSomethingElse(jsObj); }');
Object value = ((Invocable) engine).invokeFunction("doSomething", rawJSON);
Run Code Online (Sandbox Code Playgroud)
这可以按预期工作,但所有这些JSON解析来回都很重,感觉可能有更简单,更快速和更直接的方式来做到这一点.
那么,有没有更好的方法在Java和Javascript之间传递JSON或者在我的Java代码中创建兼容的JS对象?
我已经看过使用mustache.js进行模板渲染的这个指南,但它做的几乎是一样的.
谢谢 !
我需要以某种方式深度克隆我的ScriptEngine对象的整个绑定集.
到目前为止,我已经尝试过Cloner库来克隆整个Bindings结构.如果它有用,那将是很好的,因为它可以确保精确的副本,包括私有变量.但这会导致jvm堆损坏(jvm只是崩溃,退出代码为-1073740940).有时它不会崩溃,但会发生奇怪的事情,比如System.out.println()停止工作应该......
我还研究了使用ScriptEngine中的js代码克隆对象,这样我就可以将它们作为NativeObjects获取并在一些java地图中管理它们.但是我发现的所有克隆方法都存在缺陷.我想要一个精确的对象快照.例如,如果每两个对象A和B的包含字段(比如a.fa和b.fb),其引用相同的对象C,使用克隆时jQuery.extend()(例如)的字段a.fa和b.fb克隆的a和b的将引用的不同的克隆c,而不是引用一个相同的克隆.还有许多其他边缘问题.
我还尝试使用Cloner克隆整个ScriptEngine(不仅仅是绑定),我还尝试使用Rhino的js引擎并克隆整个范围(而不是Bundeled ScriptEngine包装器).但堆腐败问题仍然存在.
我需要这个,因为我必须能够将整个ScriptEngine绑定的值恢复到之前的某个点.我需要制作绑定的精确快照.
该应用程序是我的博士研究项目的一部分,该项目包括运行状态机和节点(在java中实现),其中附带了js代码.js代码由最终用户输入,并且在运行时被逐出.当无法通过路径到达最终状态时,算法会向后退步,尝试查找备用路径.在每个步骤向后,它必须撤消js引擎绑定中可能发生的任何更改.
所有全局变量名称在js evaling之前都是已知的,并且是对象(用户在节点的代码中键入,然后将其组织(在java中)到具有某些名称模式的js对象中).但是他们的内容可以是任何东西,因为它是由用户js代码控制的.
所以我想我现在唯一的解决方法是使用js代码克隆js对象.
我有以下代码可行:
ScriptEngine jsEngine = ScriptEngineManager.new().getEngineByName("nashorn");
jsEngine.eval("some script");
jsEngine.invokeMethod(jsEngine.eval("foo"), "bar");
Run Code Online (Sandbox Code Playgroud)
但我想使用预编译的脚本,所以每次我需要运行它时都不必评估脚本,所以我正在尝试;
ScriptEngine jsEngine = ScriptEngineManager.new().getEngineByName("nashorn");
CompiledScript compiledJS = jsEngine.compile("some script");
Run Code Online (Sandbox Code Playgroud)
但后来我不知道如何处理CompiledScript,我该如何调用方法呢?它显然没有实现除eval()以外的任何东西:https://docs.oracle.com/javase/8/docs/api/javax/script/CompiledScript.html
在C#中使用IActiveScriptParse32 :: ParseScriptText时,有人遇到过内存泄漏问题吗?我需要一个能够解析JavaScript代码的ScriptEngine。(除已使用的内存外,一切正常
问题是,传递的JavaScript代码越长,函数“ ParseScriptText”分配的非托管内存就越多。
我不知道如何释放分配的空间。我实际上在解析脚本后已经运行了Marshal.ReleaseComObject(parse32),但是以某种方式使用的内存不再减少。
如何从 groovy 获取执行 javascript 代码的结果?我尝试了以下操作,但我总是返回字符串“world”。我本来期望的是一个物体或地图。
import javax.script.ScriptEngineManager
import javax.script.SimpleBindings
def manager = new ScriptEngineManager()
manager.getEngineByName("JavaScript").eval("""
{hello: name}
""", [name:'world'] as SimpleBindings)
Run Code Online (Sandbox Code Playgroud) 开发基于 java 的游戏,使用 javax.script 进行 AI;
public class AI implements Runnable {
private boolean alive = true;
String scriptStr;
ScriptEngine scriptEngine;
ScriptContext scriptContext;
Bindings engineScope;
public AI() {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
scriptEngine = scriptEngineManager.getEngineByName("JavaScript");
scriptContext = new SimpleScriptContext();
engineScope = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
engineScope.put("scene", Scene.instance);
try {
scriptStr = new Scanner(new File(getClass().getResource("ai.js").getPath())).useDelimiter("\\Z").next();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (alive) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Iterable<IUnit> units …Run Code Online (Sandbox Code Playgroud) 我有一个字符串形式的 JavaScript 对象(实际上来自数据库),我需要使用 Nashorn (Java 8)将其传递给 Javascript 函数。引擎将传递的参数视为 JavaScript 中的字符串。我希望它能够将其识别为 Javascript 对象。
下面是代码片段:
String script = "function genData(dataModel) { return 'hello world '+ dataModel.url.value + ' done'; }";
//"{url : {value : "abc.com",type : "string"},layout : {value : "",type : "string"}}";
String dataModel = "{url : {value : \"abc.com\",type : \"string\"},layout : {value : \"\",type : \"string\"}}";
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
Invocable inv = (Invocable) engine;
result = inv.invokeFunction("genData", dataModel);
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
javax.script.ScriptException: TypeError: Cannot read …
我正在尝试在 java 8 (1.8.0_102) 中执行 javascript (ES6) 函数。
这是精简后的 javascript 片段。
const myfunc = (args) => {
if (!(args.name || args.zip))
return
const result = {...args}
const { name, zip, date } = result
...
}
Run Code Online (Sandbox Code Playgroud)
这是我的java代码
public static Object processArbitraryJavaScript(String params)
{
String[] options = new String[] {"--language=es6"};
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
NashornScriptEngine engine = (NashornScriptEngine) factory.getScriptEngine(options);
Object result = null;
try
{
engine.eval(new FileReader("sample.js"));
Invocable inv = (Invocable) engine;
result = inv.invokeFunction("myfunc", params);
}
catch (ScriptException scriptException …Run Code Online (Sandbox Code Playgroud)