Несколько экземпляров CompiledScript - PullRequest
0 голосов
/ 21 января 2019

Я загружаю скрипт Scala через ScriptEngine и использую CompiledScript для его проверки.

Я использую интерфейс Java для сопоставления скрипта Scala со стороной Java, как показано ниже.

Интерфейс Java:

public interface SomeInterface {
     void method1();
}

Scala Скрипт:

class ScalaImp extends SomeInterface {
   override def method1() : Unit = {
    //Implementation
   }

}

Код, который загружает объект типа SomeInterface, выглядит следующим образом.

String extension = path.getFileName().toString();
extension = extension.substring(extension.lastIndexOf(".") > 0 ? extension.lastIndexOf(".") + 1 : 0);
ScriptEngine engine = new ScriptEngineManager().getEngineByExtension(extension);
File file = path.toFile();

if (file.exists() && file.isFile()) {
    SomeInterface mappingInterface = null;
    SomeInterface mappingInterface2 = null;
    try(FileReader fr = new FileReader(file)) {

        Compilable compilable = (Compilable)engine;
        CompiledScript compiledScript = compilable.compile(fr);

        mappingInterface = (SomeInterface)compiledScript.eval();
        mappingInterface2 = (SomeInterface)compiledScript.eval(); //This fails. Any alternative for this?

    }
    catch (FileSystemException e) {
        logger.error("Cannot load file");
    }

    return mappingInterface;
}

Я хочу создать несколько экземпляров сценария. Но приведенный выше код выдает следующую ошибку: Failed to load '$line6.$eval': $line6.$eval при втором eval() вызове. Я знаю, что могу использовать несколько экземпляров CompiledScript и оценивать их отдельно. Но компиляция занимает слишком много времени и превышает ожидаемую производительность программы.

В любом случае можно ли создать несколько экземпляров одного и того же сценария с одним экземпляром CompiledScript?

1 Ответ

0 голосов
/ 21 января 2019

Не совсем.Он работает с использованием REPL, который всегда компилируется для оценки кода в 2.12 и более ранних версиях.

Возможно, вы пытаетесь:

$ scala
Welcome to Scala 2.12.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_144).
Type in expressions for evaluation. Or try :help.

scala> val s = scala.tools.nsc.interpreter.Scripted()
s: scala.tools.nsc.interpreter.Scripted = scala.tools.nsc.interpreter.Scripted@432f4626

scala> s.eval("class C")
res0: Object = null

scala> val c = s.compile("new C")
c: javax.script.CompiledScript = scala.tools.nsc.interpreter.Scripted$WrappedRequest@13346a64

scala> c.eval()
res1: Object = C@2d093067

scala> c.eval()
res2: Object = C@2693e39c

Вы можете наблюдать за работой компиляции:

scala> s.intp.settings.Xprint.value_=(List("typer"))

На втором eval он повторно использует класс, который упаковывает код пользователя, но компилирует новую оболочку, которая пересылает определения.Похоже, есть ошибка, при которой он пытается пересылать как определения значений, так и типы;в этом случае определение класса не работает.

Возможно, вы не намерены определять два разных класса, а возвращаете два экземпляра одного и того же класса, как показано?

...