Rhino(
http://www.mozilla.org/rhino/)已经被集成在JDK6中的JSR223 Scripting框架中。但是在JDK5中使用Rhino的E4X功能是不行的,因为默认情况下该功能是被关闭的,如果想要在JDK5中使用Rhino的E4X功能,就需要一些额外的代码。
查看Rhino的ContextFactory的源代码可以看到,与E4X相关的Context.FEATURE_E4X是在JDK6的时候才返回true的。所以首先需要实现自己的ContextFactory,做如下修改就可以了:
java 代码
- public class E4XContextFactory extends ContextFactory {
- protected boolean hasFeature(Context cx, int featureIndex) {
- switch (featureIndex) {
- case Context.FEATURE_E4X:
- return true;
- }
- return super.hasFeature(cx, featureIndex);
-
- }
-
- }
我们需要在自己的ContextFactory生成的Context中执行JavaScript,这个时候需要使用ContextAction,实现该接口:
下面是一个可以运行某个JavaScript文件的ContextAction实现:
java 代码
- private static class E4XAction implements ContextAction {
- private File file;
-
- public E4XAction(File file) {
- this.file = file;
- }
-
- public Object run(Context context) {
- try {
-
- Global global = new Global(context);
- InputStream ins = new FileInputStream(file);
-
- Reader reader = new InputStreamReader(ins);
- Object result = context.evaluateReader(global, reader, file
- .getName(), 1, null);
- return Context.toString(result);
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- return “!!!ERROR!!!”;
- }
-
- }
-
接下来就是使用此ContextAction了:
java 代码
- File file = new File(”e4xsimple.js”);
- E4XContextFactory ecf = new E4XContextFactory();
- System.out.println(ecf.call(new E4XAction(file))).toString());
测试文件e4xsimple.js的内容为:
js 代码
- var a = <order><person>alex</person></order>;
-
- print (a.person);
-
输出是:alex
注意事项
1.把下载到的XMLBeans的lib下面的xbean.jar和jsr173_1.0_api.jar都放到classpath中,否则会报错,说找不到XML这个名字。如果你只放了xbean.jar的话,也会出错。我一开始只放了xbean.jar,出错提示不明显,后来我debug跟踪到 org.mozilla.javascript.xmlimpl.XMLLib在初始化的时候出现了javax.xml.stream的相关类的ClassNotFound的错误,导致XML相关的名称没有被加载。这是因为xbean.jar依赖于jsr173_1.0_api.jar。而网上的教程都说只放xbean.jar就可以,在JDK6中是可以的,因为JDK6的rt.jar中已经添加了JSR173,即javax.xml.stream包,而JDK5中是没有的。
2.如果你想在JavaScript中使用print命令,可以把org.mozilla.javascript.tools.shell.Global拷贝过来加以修改就可以了。我就是这么做的,在执行脚本的时候使用该Global对象。需要去掉一些不用的名称使得编译通过。