GroovyShell — ошибка при разделении скрипта на две части (MissingMethodExceptionNoStack)

Я совершенно новичок в Groovy, поэтому надеюсь, что ответ не очевиден...

Допустим, у меня есть скрипт "Test.groovy":

class A {
    def greet() {println "Hey there!"}
}

new A().greet()

И я оцениваю этот скрипт с помощью GroovyShell (из Java):

new GroovyShell().evaluate(new File("Test.groovy"));

Я получаю ожидаемый результат:

Привет!

Теперь, когда я удаляю последнюю строку из сценария и вместо этого оцениваю ее в отдельном вызове evaluate(), я получаю довольно неясное исключение.

"Test.groovy":

class A {
    def greet() {println "Hey there!"}
}

Джава:

GroovyShell shell = new GroovyShell();
shell.evaluate(new File("Test.groovy"));
shell.evaluate("new A().greet()");

org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: нет подписи метода: A.main() применим для типов аргументов: ([Ljava.lang.String;) значения: [[]] Возможные решения: wait(), ожидание (длинное), любое (), поиск (), ожидание (длинное, целое), каждое (groovy.lang.Closure)

Еще смешнее, если я оставлю скрипт как есть и поменяю только часть Java, он работает отлично (получаю два "Привет!")


person Eric Leibenguth    schedule 24.08.2015    source источник


Ответы (1)


Это должно помочь объяснить, что вы видите: http://www.groovy-lang.org/structure.html#_script_class

Groovy рассматривал ваш первый файл .groovy как сценарий, потому что последняя строка существовала вне объявления класса. Groovy компилируется в байт-код Java, а Java требует, чтобы весь код был определен в классе. Чтобы соответствовать требованиям, Groovy проделал некоторую магию и динамически преобразовал ваш сценарий в класс Java с помощью метода main — что-то вроде этого:

public class script1440427072752 extends groovy.lang.Script { 

    public script1440427072752() {
    }

    public script1440427072752(groovy.lang.Binding context) {
        super(context)
    }

    public static void main(java.lang.String[] args) {
        org.codehaus.groovy.runtime.InvokerHelper.runScript(script1440427072752, args)
    }

    public java.lang.Object run() {
        new A().greet()
    }

}
public class A extends java.lang.Object { 

    public java.lang.Object greet() {
        this.println('Hey there!')
    }

}

Однако когда вы удалили эту строку, Groovy расценил ваш файл .groovy как типичный класс Java с именем A. Динамический перевод в groovy.lang.Script не требуется.

Когда вы попытались выполнить A, GroovyShell искал метод main, не смог его найти и выдал эту ошибку.

person bdkosher    schedule 24.08.2015