Java 7 + Rhino 1.7R3 支持 CommonJS 模块
Java 7 + Rhino 1.7R3 support for CommonJS modules?
我需要帮助让CommonJS在Java 7和Rhino 1.7R3上运行。
Rhino 1.7R3 支持 CommonJS 模块:
- https://developer.mozilla.org/En/New_in_Rhino_1.7R3
Java 7 与 Rhino 1.7R3 捆绑在一起。不幸的是,Java 7的Rhino是一个修改版本,它不包括org.mozilla.javascript.commonjs
包:
- http://jdk7.java.net/rhino/README.TXT
我想通过 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 支持?
编辑:我发现了以下问题,它涉及完全相同的主题:
健全性检查:Rhino 没有必需功能,对吧?
受访者建议,也许可以用CommonJS Rhino 1.7R3替换有限的Rhino 1.7R3,但没有说明如何做到这一点。这就是我在这里要问的。
编辑:似乎你根本不需要使用JVM引导类加载器。Sun 已将默认的 Rhino 实现类放入
sun.org.mozilla.javascript.*
包。但是你加载的 Rhino 实现会占用
org.mozilla.javascript.*
因此,它们不应该发生碰撞。但是,如果出现问题,您可以在引导类加载器的帮助下覆盖JDK中的类。您有两种选择:
基本上,你需要覆盖类路径,以便你的 Rhino 类优先而不是内置类。
- 只需将 rhino-1.7R3.jar 放到 your-JRE-path''lib''ext。这样,Rhino jar 将被添加到 Java Bootsrap 类加载器中,并在内置的 JavaScript jar 之前加载。
或者,如果您无权访问../lib/ext 您可以使用命令行选项:
-Xbootclasspath/a:path/to/rhino-1.7R3.jar
Rhino 本身没有实现 Java 脚本 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
和其他相关类。了解甲骨文是如何做到的。但请注意,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的解决方案。
- 看看浏览器化。它是一个JavaScript预处理器,它将你的源代码组合成一个捆绑包。
- 重写模块,使其使用 AMD 或 UMD,然后将它们与 r.js 工具组合。
这两个选项都要求您在生成过程中添加 js 预处理步骤,并且可能会使调试代码有点困难。
这个问题已经很老了,但对于那些从谷歌来到这里的人,你可以用下面的话在 Rhino 中设置 CommonJS 支持(下面只是一种方法):
(我只是直接调用 Rhino,而不是使用 Java 的脚本 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();
现在您可能有两个文件:
主.js
require('require-test.js')()
要求测试.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;
一切正常。
- jQuery-2.1.1.min.js或最新版本jQuery-2.13.min.js不会't支持'@
- jQuery检测浏览器是否支持Zoom
- 错误:对象没有't支持'自动完成'
- EmberJS中支持单字母单词模型
- javascript中的命名空间,IDE中支持代码完成/内容辅助's
- Internet Explorer缺少占位符支持,特别是密码字段
- 为什么我得到错误IE修剪方法是't支持
- 任何浏览器都不支持javascript函数
- GTK百老汇支持同时连接
- JQuery示例不起作用-“;对象没有't支持属性或方法'按钮'&”;
- 对象不支持属性或方法“自动完成”
- 如何捆绑commonjs模块,除非指定需要
- 对象没有'不支持set_viewXML
- Javascript Q库浏览器支持
- 您的平台不支持RxJS-Array.observe
- React Native当前是否支持访问用户'的通讯簿
- 将HTML(支持文件)中的令牌(字符串、数字等)传递给LogiXML
- 错误:语法错误,无法识别的表达式:不支持的伪:无效/RectJS/Unit Testing
- Excellen导出xlsx支持
- Java 7 + Rhino 1.7R3 支持 CommonJS 模块