如何在 CQ 5.6 中启用 Rhino(或任何 JavaScript 引擎)?

How to enable Rhino (or any JavaScript Engine) in CQ 5.6?

我有一些自定义逻辑,需要计算一个简单的布尔表达式。在我的 IDE 中,我有一些单元测试 运行 很好,但是当我试图在我的 CQ 5.6.1 实例上使用它时,ScriptEngineManager 找不到 JavaScript 引擎。虽然这应该是任何环境中标准 java 安装的一部分。

ScriptEngineManager sef = new ScriptEngineManager();
ScriptEngine se = sef.getEngineByName("JavaScript");

在 pom 中,我有以下通常有帮助的内容:

<Import-Package>*;resolution:=optional</Import-Package>

通常,当您不将其放入 sling.properties 中的引导委托时,一些系统库不会在 OSGi 中公开,但这也不起作用:

org.osgi.framework.bootdelegation=org.w3c.*,com.sun.script.*,com.yourkit.*, ${org.apache.sling.launcher.bootdelegation}

我还能尝试什么?

编辑: 还有关于我对基督徒回答的评论。我发现OSGi中应该有一个服务: http://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/javascript/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineFactory.java

但是当我尝试使用以下代码引用它时,我的 servlet 不再处于活动状态:

@Reference
private transient ScriptEngineFactory sef = null;

所以它似乎由于某种原因无法注入工厂。我已经看到可能有不止一种服务实现了这个接口,我如何定位正确的服务(上面链接)?

编辑2: 我现在甚至尝试直接引用 Rhino 工厂:

@Reference(target = "(component.name=org.apache.sling.scripting.javascript.internal.RhinoJavaScriptEngineFactory)")
private transient ScriptEngineFactory sef = null;

有了这个,我的 servlet 告诉我它很满意:

["Satisfied","Service Name: javax.script.ScriptEngineFactory","Target Filter: (component.name=org.apache.sling.scripting.javascript.internal.RhinoJavaScriptEngineFactory)","Multiple: single","Optional: mandatory","Policy: static","Bound Service ID 2004 (org.apache.sling.scripting.javascript.internal.RhinoJavaScriptEngineFactory)"]

但是如果我访问我的 servlet,它不会被触发并且 SlingDefaultServlet 接管。没有上面的@Reference它是可以访问的,所以它必须做一些事情。

您需要一个支持 OSGi 的 ScriptEngineManager。参见 https://devnotesblog.wordpress.com/2011/09/07/scripting-using-jsr-223-in-an-osgi-environment/

经过将近一整天的反复试验,我发现了 2 个主要问题:

第一:我的编译器插件设置为使用1.8;我必须将其恢复为 1.6,这样我的 maven-scr-plugin 才能再次创建正确的清单,并且 OSGi 服务的注入确实有效:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
        <encoding>UTF-8</encoding>
    </configuration>
</plugin>

我必须稍后研究如何将其增加到至少 1.7(我尝试过但也没有用)。

其次,我的问题的实际答案很简单:

@Reference
private transient ScriptEngineManager sem = null;

此外,我必须使用 javascript 而不是 JavaScript 作为经理的 getEngineByName 方法。要查看为引擎注册的内容,您可以在 OSGi 控制台中查看以下路径:

/system/console/status-slingscripting

列出了所有可用的ScriptEngine及其注册名称、扩展名和 MIME 类型。