Как настроить сценарии jsr223 с помощью scala в качестве языка сценариев

До сих пор я пробовал реализацию sling для сценариев jsr223 для scala, но не смог правильно настроить ее. когда я делаю это:

public static void main(String[] args) {
    try {
        new ScriptEngineManager().getEngineByName("scala").
          eval("object HelloWorld {def main(args: Array[String]) { 
                  println(\"Hello, world!\") }}");
    } catch (ScriptException e) {
        e.printStackTrace();
    }
}

Я не получил ничего, кроме:

javax.script.ScriptException: ERROR 
org.apache.sling.scripting.scala.Script line 13 : not found: type 
Script at org.apache.sling.scripting.scala.ScalaScriptEngine.eval(ScalaScriptEngine.scala:117)
    at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)

подобные проблемы обсуждаются здесь: http://scala-programming-language.1934581.n4.nabble.com/How-to-compile-Scala-code-from-java-using-the-current-ClassLoader-вместо-строки-основанный-classpat-td1955873.html#a1955873

и

http://dev.day.com/discussion-groups/content/lists/sling-dev/2009-12/2009-12-01_Scala_scripting_support_was_Re_And_another_one____Michael_D_rig.html

возможно, есть другая реализация, о которой я не знаю.

Любая помощь приветствуется


person VivaceVivo    schedule 13.04.2011    source источник


Ответы (3)


Взгляните на тестовые примеры в модуле scala/script в Apache Sling для рабочего примера. Сценарий и его точка входа (то есть объект) должны следовать определенным соглашениям. Я предоставлю больше информации об этом, если потребуется, позже.

Общий обзор скриптового движка см. в моих слайдах сессии с Scala Days 2010. .

Обновление. Скрипты должны иметь следующую форму:

package my.cool.script {
  class foo(args: fooArgs) {
    import args._ // import the bindings
    println("bar:" + bar)
  }
}

Тип args создается механизмом сценариев и назван в честь простого класса имя сценария с добавлением «Args». Далее в примере предполагается, что Bindings переданы для оценки сценария содержит значение для имени «бар». Дополнительные сведения см. в комментарии к классу на странице ScalaScriptEngine.

Вам нужно передать имя вашего класса скрипта обработчику скриптов. Вы делаете это, помещая полное имя сценария (например, my.cool.script.foo) в ScriptContext по имени scala.script.class.

person michid    schedule 13.04.2011

С заключением https://issues.scala-lang.org/browse/SI-874 в версии 2.11 это должно быть так же просто, как показано в заявке:

import javax.script.*;
ScriptEngine e = new ScriptEngineManager().getEngineByName("scala");
e.getContext().setAttribute("label", new Integer(4), ScriptContext.ENGINE_SCOPE);
try {
    engine.eval("println(2+label)");
} catch (ScriptException ex) {
    ex.printStackTrace();
}
person Oswaldo    schedule 02.06.2013
comment
В текущей версии Scala 2.11.0-M4 необходимо выполнить дополнительную работу по настройке среды для использования пути к классам java: ... List nil = Nil$.MODULE$; $colon$colon vals = $colon$colon$.MODULE$.apply((String) true, nil); ((IMain)engine).settings().usejavacp().tryToSet(vals); - person VivaceVivo; 22.10.2013

К сожалению, мой комментарий был нечитаем без разрывов строк - так что...

Чтобы иметь возможность запускать упомянутый Codesnippet, мне нужно было внести следующие изменения. Я использовал Scala 2.11.0-M4

public static void main(String args[]){
  ScriptEngine engine = new ScriptEngineManager().getEngineByName("scala");

  // Set up Scriptenvironment to use the Java classpath
  List nil = Nil$.MODULE$;
  $colon$colon vals = $colon$colon$.MODULE$.apply((String) "true", nil);
  ((IMain)engine).settings().usejavacp().tryToSet(vals);ScriptContext.ENGINE_SCOPE);

  engine.getContext().setAttribute("labelO", new Integer(4), ScriptContext.ENGINE_SCOPE);
  try {
    engine.eval("val label = labelO.asInstanceOf[Integer]\n"+
                "println(\"ergebnis: \" + (2 + label ))");
  } catch (ScriptException ex) {
    ex.printStackTrace();
  }
}
person VivaceVivo    schedule 22.10.2013
comment
примечание: текущий Milestone 2.11.0-M5 имеет ошибку и возвращает NULL для getEngineByName(scala) Issues.scala-lang.org/browse/SI-7843 M6 должен работать (я не проверял) - person VivaceVivo; 22.10.2013