![](/img/trans.png)
[英]Do any IDEs/IDE plugins have support for JavaScript CommonJS modules?
[英]Java 7 + Rhino 1.7R3 support for CommonJS modules?
我需要帮助让CommonJS使用Java 7和Rhino 1.7R3。
Rhino 1.7R3支持CommonJS模块:
Java 7与Rhino 1.7R3捆绑在一起。 不幸的是,Java 7的Rhino是一个修改版本,它不包括org.mozilla.javascript.commonjs
包:
我想通过javax.script
API使用Rhino 1.7R3对CommonJS的支持,如下所示:
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
engine.put("markdown", markdown);
engine.eval("var html = require('./Markdown.Sanitizer').getSanitizingConverter().makeHtml(markdown);");
return (String) engine.get("html");
(我通过ScriptEngineManager
验证我确实使用的是Rhino 1.7R3引擎。)我想也许我可以将以下依赖项添加到类路径中
<dependency>
<groupId>org.mozilla</groupId>
<artifactId>rhino</artifactId>
<version>1.7R3</version>
</dependency>
和CommonJS一样, require()
- 将开始工作。 但事实并非如此。 当我尝试使用require()
我得到了
Caused by: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "require" is not defined. (<Unknown source>#2)
at sun.org.mozilla.javascript.internal.ScriptRuntime.constructError(ScriptRuntime.java:3773)
at sun.org.mozilla.javascript.internal.ScriptRuntime.constructError(ScriptRuntime.java:3751)
at sun.org.mozilla.javascript.internal.ScriptRuntime.notFoundError(ScriptRuntime.java:3836)
如何让Java 7与完整版Rhino 1.7R3一起使用,以便获得CommonJS支持?
编辑:我发现了以下问题,它涉及完全相同的主题:
受访者表示也许可以用CommonJS Rhino 1.7R3替换有限的Rhino 1.7R3,但没有说明如何做到这一点。 这就是我在这里问的问题。
编辑 :看起来你毕竟不需要使用JVM引导程序类加载器。 Sun已将默认的Rhino实现类放入其中
sun.org.mozilla.javascript.*
包。 但是你加载的Rhino实现将会占用
org.mozilla.javascript.*
因此他们不应该碰撞。 但是, 如果出现问题,您可以在bootstrap类加载器的帮助下覆盖JDK中的类。 您有两种选择:
基本上你需要覆盖类路径,以便你的Rhino类优先于内置而不是内置类。
或者,如果您无法访问../lib/ext,则可以使用命令行选项:
-Xbootclasspath/a:path/to/rhino-1.7R3.jar
Rhino本身不实现Java Scripting API。 为了将Rhino集成到JDK中,Sun已经实现了自己的ScriptEngine
和ScriptEngineFactory
。 因此,如果您加载自己的rhino-1.7R3.jar
,如果加载脚本,则无法使用Common JS
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
相反,你有两个选择。
在Rhino API之上 实现您自己的 ScriptEngine
, ScriptEngineFactory
和其他相关类。 了解Oracle如何做到这一点 。 但请注意,JDK源代码属于GPL 2许可证,因此您应该为Rhino发布自定义脚本引擎包装器,或者仅将这些类用作参考,不要复制代码。
直接使用Rhino API 。 我强烈推荐这种方法。 Mozilla网站上有文档和示例,但基本API相对简单:
// Execution environment for Rhino // there should be only one context in a giver thread Context cx = Context.enter(); // Object.prototype, Function prototype, etc. Scriptable scope = cx.initStandardObjects(); // Execute script from a given java.io.Reader Object result = cx.evaluateReader(scope, reader, 0, null); // If returning result isn't sufficient for your needs // you can do something like this: Object someVar = scope.get("someVar"); // Don't forget to close the context when you're done Context.exit();
或者,我可以为您提供一些仅限JS的解决方案。
这两个选项都要求您在构建过程中添加一个js预处理步骤,并且可能会使调试代码变得有点困难。
这个问题已经过时了,但对于那些来自谷歌的人来说,您可以使用以下方法在Rhino中设置CommonJS支持(以下只是一种方式):
(我只是直接调用Rhino,而不是使用Java的Scripting API)
List<URI> paths = Arrays.asList(new URI[] { new File("js/require/paths/here").toURI() });
Context ctx = Context.enter();
Scriptable scope = ctx.initStandardObjects();
new RequireBuilder()
.setModuleScriptProvider(new SoftCachingModuleScriptProvider(
new UrlModuleSourceProvider(paths, null)))
.setSandboxed(true)
.createRequire(ctx, scope)
.install(scope);
//
// now you can ctx.evaluateString(...) and use require()
//
Context.exit();
现在您可能有两个文件:
require('require-test.js')()
module.exports = function() {
java.lang.System.out.println('The CommonJS require function works!')
}
如果您使用Gradle
构建系统。 我通过在项目gradle文件中添加此依赖项成功修复了此问题。 (基于这里 )
compile group: 'org.mozilla', name: 'rhino', version: '1.7.10'
并且您必须将导入的包名称从sun.org.mozilla.javascript.internal
为java类文件中的org.mozilla.javascript
。
// import sun.org.mozilla.javascript.internal.NativeObject; // <=== Do not use this package.
import org.mozilla.javascript.NativeObject;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
一切正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.