是否可以从类路径中获取Nashorn加载脚本?

时间:2015-01-29 17:33:25

标签: java clojure nashorn

在解析URI时,是否可以让Nashorn的load方法使用项目的类路径?

这是我正在尝试做的事情:

(defn create-engine
  "Creates a new nashorn script engine and loads dependencies into its context."
  [dependencies]
  (let [nashorn (.getEngineByName (ScriptEngineManager.) "nashorn")
        scripts (map #(str "load('" % "');") dependencies)]
    (.eval nashorn "var global = this;")
    (doseq [script scripts] (.eval nashorn script))
    nashorn))

(def app "public/javascripts/app.js") ; in /resouces, on classpath


; resulting exception:
clojure.lang.Compiler$CompilerException: 
javax.script.ScriptException: TypeError: 
Cannot load script from public/javascripts/app.js in <eval> at line number 1

3 个答案:

答案 0 :(得分:7)

Nashorn的load()方法实际上支持使用前缀为classpath:的网址。它将从类路径加载该前缀后面的文件。查看来源 - http://cr.openjdk.java.net/~sundar/8025629/webrev.01/src/jdk/nashorn/internal/runtime/Context.java.html第502行。

答案 1 :(得分:3)

绝对路径应始终以斜杠"/public/javascripts/app.js"开头,但我不确定load()是否从类路径加载,如果不是,则可能必须使用eval(Reader)方法并自己构建读者

编辑:

如果路径在jar中是绝对路径,则需要使用类路径资源的开头斜杠。没有斜杠意味着相对于你从中调用它的特定类。您应该获得资源的InputStream并评估读者,使用Java看起来像这样:

nashorn.eval (new InputStreamReader (getClass().getResourceAsStream("/public/javascripts/app.js")));

我不想把它翻译成clojure,因为那肯定会以失败告终。

EDIT2:

那么这是一次尝试:

(defn create-engine
  "Creates a new nashorn script engine and loads dependencies into its context."
  [dependencies]
  (let [nashorn (.getEngineByName (ScriptEngineManager.) "nashorn")]
    (.eval nashorn "var global = this;")
    (doseq [dependency dependencies] (.eval nashorn (new InputStreamReader (.getResourceAsStream String dependency))))
    nashorn))

如果这开始了核战争或其他什么,我将不会被追究责任

答案 2 :(得分:0)

你应该使用clojure.java.io/resource

(def nashorn (.. (javax.script.ScriptEngineManager.) (getEngineByName "nashorn")))
(.eval nashorn (clojure.java.io/reader (clojure.java.io/resource "jvm-npm.js")))

确保您的lein项目中配置了资源文件夹:

:resource-paths ["src/resources"]