jira.codehaus.org

  • Log In Access more options
    • Online Help
    • Keyboard Shortcuts
    • About JIRA
    • JIRA Credits
    • What?s New
  • Dashboards Access more options (Alt+d)
  • Projects Access more options (Alt+p)
  • Issues Access more options (Alt+i)
  • groovy
  • GROOVY-3707

I wish i could parse a class using eval function of JSR223

  • Log In
  • Views
    • XML
    • Word
    • Printable

Details

  • Type: Wish Wish
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Duplicate
  • Affects Version/s: 1.6.4
  • Fix Version/s: None
  • Component/s: JSR / TCK / GLS
  • Labels:
    None
  • Testcase included:
    yes

Description

Verbose version of the test passes, but it is a little ugly.

    public static final String FOO_CLASS = "class Foo { int getResult() { return 1; } } ; Foo.class";
    public static final String FOO = "class Foo { int getResult() { return 1; } }";

    public void testClassEvalVerbose() throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");
        assertEquals("Foo", ((Class) engine.eval(FOO_CLASS)).getCanonicalName());
    }

    public void testClassEvalBrief() throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");
        assertEquals("Foo", ((Class) engine.eval(FOO)).getCanonicalName());
    }

Brief version throws:
javax.script.ScriptException: javax.script.ScriptException: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: Foo.main() is applicable for argument types: ([Ljava.lang.String values: [[]]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:119)
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
at com.jtstand.TestStepScriptTest.testClassEvalBrief(TestStepScriptTest.java:42)
Caused by: javax.script.ScriptException: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: Foo.main() is applicable for argument types: ([Ljava.lang.String values: [[]]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:307)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:113)
... 28 more
Caused by: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: Foo.main() is applicable for argument types: ([Ljava.lang.String values: [[]]

Why?
Is this what JSR223 specifies to do?
To sad if yes!

Issue Links

is duplicated by

Improvement - An improvement or enhancement to an existing feature or task. GROOVY-3816 Should be possible to declare a class in a script and use it in another script with JSR223

  • Major - Major loss of function.
  • Closed - The issue is considered finished, the resolution is correct. Issues which are not closed can be reopened.

Activity

Ascending order - Click to sort in descending order
  • All
  • Comments
  • Work Log
  • History
  • Activity
Hide
Permalink
blackdrag blackdrag added a comment - 27/Aug/09 7:21 PM

I think it says to execute the script whatever this means. The main method is called from within Groovy code. InvokerHelper#createScript is responsible for it in the end. But here basically is a problem. Should a class be executed? or should the class be returned? A script is a class to. It behaves a bit different, but it is in fact a class, one with a run method, that will be called directly. The current code does anything that is no script in a script, that executes a main method of the wrapped class. Well, maybe wrapper is so good not, proxy is probably better.

What for example if your class is a junit test. Do you expect it to be executed, or the class being returned? Executing it means to run the test, returning the class means not executing it. You probably say the script returns a class, but there is no script, just the class. The script is a short form of creating a certain kind of class. So for Groovy the basic concept is the class, not the script. From that point of view it behaves absolutely correct.

Show
blackdrag blackdrag added a comment - 27/Aug/09 7:21 PM I think it says to execute the script whatever this means. The main method is called from within Groovy code. InvokerHelper#createScript is responsible for it in the end. But here basically is a problem. Should a class be executed? or should the class be returned? A script is a class to. It behaves a bit different, but it is in fact a class, one with a run method, that will be called directly. The current code does anything that is no script in a script, that executes a main method of the wrapped class. Well, maybe wrapper is so good not, proxy is probably better. What for example if your class is a junit test. Do you expect it to be executed, or the class being returned? Executing it means to run the test, returning the class means not executing it. You probably say the script returns a class, but there is no script, just the class. The script is a short form of creating a certain kind of class. So for Groovy the basic concept is the class, not the script. From that point of view it behaves absolutely correct.
Hide
Permalink
Roshan Dawrani added a comment - 27/Aug/09 10:35 PM

If I want to see how groovy gets JSR223 enabled, what code can I look at? Is that part of the core groovy codebase?

Show
Roshan Dawrani added a comment - 27/Aug/09 10:35 PM If I want to see how groovy gets JSR223 enabled, what code can I look at? Is that part of the core groovy codebase?
Hide
Permalink
Albert Kurucz added a comment - 28/Aug/09 12:01 AM

If I look at FOO as a script, it is a single statement which defines a Class type Object with the name Foo, and it (the Class!) should be returned by the evaluator, just like in this example i is returned:

    public static final String I = "Integer i = 1";

    public void testClassI() throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");
        assertEquals(1, engine.eval(I));
    }

Every Class is an Object. Right?
See:
http://java.sun.com/javase/6/docs/api/java/lang/Class.html

Show
Albert Kurucz added a comment - 28/Aug/09 12:01 AM If I look at FOO as a script, it is a single statement which defines a Class type Object with the name Foo, and it (the Class!) should be returned by the evaluator, just like in this example i is returned:
    public static final String I = "Integer i = 1";

    public void testClassI() throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");
        assertEquals(1, engine.eval(I));
    }
Every Class is an Object. Right? See: http://java.sun.com/javase/6/docs/api/java/lang/Class.html
Hide
Permalink
Albert Kurucz added a comment - 28/Aug/09 12:49 AM

Regarding "You probably say the script returns a class, but there is no script, just the class."

Would you say BAR is not a script, just classes?

public static final String FOOBAR = "class Foo { int getResult() { return 1; } } ; class Bar extends Foo { int getResult() { return super.getResult() + 1; } } ; Bar b = new Bar(); b.getResult()";
    public static final String BAR = "class Foo { int getResult() { return 1; } } ; class Bar extends Foo { int getResult() { return super.getResult() + 1; } }";

    public void testFooBar() throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");
        assertEquals(2, engine.eval(FOOBAR));
    }

    public void testBar() throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");
        assertEquals("Bar", ((Class) engine.eval(BAR)).getCanonicalName());
    }

From my point of view BAR is a script with two statements, both are Class definitions. The last one should be returned: the Bar Class.
Instead of trying to execute the non-existent main method of Foo, resulting

javax.script.ScriptException: javax.script.ScriptException: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: Foo.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:119)
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
        at com.jtstand.TestStepScriptTest.testBar(TestStepScriptTest.java:34)
Caused by: javax.script.ScriptException: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: Foo.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:307)
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:113)
        ... 28 more
Caused by: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: Foo.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
Show
Albert Kurucz added a comment - 28/Aug/09 12:49 AM Regarding "You probably say the script returns a class, but there is no script, just the class." Would you say BAR is not a script, just classes?
public static final String FOOBAR = "class Foo { int getResult() { return 1; } } ; class Bar extends Foo { int getResult() { return super.getResult() + 1; } } ; Bar b = new Bar(); b.getResult()";
    public static final String BAR = "class Foo { int getResult() { return 1; } } ; class Bar extends Foo { int getResult() { return super.getResult() + 1; } }";

    public void testFooBar() throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");
        assertEquals(2, engine.eval(FOOBAR));
    }

    public void testBar() throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");
        assertEquals("Bar", ((Class) engine.eval(BAR)).getCanonicalName());
    }
From my point of view BAR is a script with two statements, both are Class definitions. The last one should be returned: the Bar Class. Instead of trying to execute the non-existent main method of Foo, resulting
javax.script.ScriptException: javax.script.ScriptException: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: Foo.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:119)
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
        at com.jtstand.TestStepScriptTest.testBar(TestStepScriptTest.java:34)
Caused by: javax.script.ScriptException: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: Foo.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:307)
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:113)
        ... 28 more
Caused by: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: Foo.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
Hide
Permalink
Albert Kurucz added a comment - 28/Aug/09 1:06 AM

Regarding
"What for example if your class is a junit test.
Do you expect it to be executed, or the class being returned?
Executing it means to run the test, returning the class means not executing it.
"

public static final String MY_THREAD = "class MyThread extends Thread { void run() { System.out.println(\"Hi there!\") } } ";

    public void testMyThread() throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");
        engine.eval(MY_THREAD);
    }

If the class is a Thread, Groovy should not try to execute it through its main method, resulting

javax.script.ScriptException: javax.script.ScriptException: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: MyThread.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:119)
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
        at com.jtstand.TestStepScriptTest.testMyThread(TestStepScriptTest.java:29)
Caused by: javax.script.ScriptException: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: MyThread.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:307)
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:113)
        ... 28 more
Caused by: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: MyThread.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]

What if the Class is a Thread but it also has a static void main(String[] args)?
Which kind of execution is the most correct kind?

I think it would be easier to just return the Class.

Show
Albert Kurucz added a comment - 28/Aug/09 1:06 AM Regarding "What for example if your class is a junit test. Do you expect it to be executed, or the class being returned? Executing it means to run the test, returning the class means not executing it. "
public static final String MY_THREAD = "class MyThread extends Thread { void run() { System.out.println(\"Hi there!\") } } ";

    public void testMyThread() throws ScriptException {
        ScriptEngineManager factory = new ScriptEngineManager();
        ScriptEngine engine = factory.getEngineByName("groovy");
        engine.eval(MY_THREAD);
    }
If the class is a Thread, Groovy should not try to execute it through its main method, resulting
javax.script.ScriptException: javax.script.ScriptException: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: MyThread.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:119)
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
        at com.jtstand.TestStepScriptTest.testMyThread(TestStepScriptTest.java:29)
Caused by: javax.script.ScriptException: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: MyThread.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:307)
        at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:113)
        ... 28 more
Caused by: org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack: No signature of method: MyThread.main() is applicable for argument types: ([Ljava.lang.String;) values: [[]]
What if the Class is a Thread but it also has a static void main(String[] args)? Which kind of execution is the most correct kind? I think it would be easier to just return the Class.
Hide
Permalink
blackdrag blackdrag added a comment - 28/Aug/09 4:26 AM

Would I say BAR is not a script, just classes? yes.
What if the Class is a Thread but it also has a static void main(String[] args)? It would execute the main method.

What if the class you write extends Script? in Current Groovy the class would be executed through its run method. In your version it should return the class too. The problem now is, that at that point we don't know the difference between a written class and a normal script anymore.

Show
blackdrag blackdrag added a comment - 28/Aug/09 4:26 AM Would I say BAR is not a script, just classes? yes. What if the Class is a Thread but it also has a static void main(String[] args)? It would execute the main method. What if the class you write extends Script? in Current Groovy the class would be executed through its run method. In your version it should return the class too. The problem now is, that at that point we don't know the difference between a written class and a normal script anymore.
Hide
Permalink
Albert Kurucz added a comment - 28/Aug/09 8:20 AM

Yes, this is how Groovy Script is designed.
I think JSR223 should specify the ScriptEngine's behavior to either yours or to mine.
You agree?

Show
Albert Kurucz added a comment - 28/Aug/09 8:20 AM Yes, this is how Groovy Script is designed. I think JSR223 should specify the ScriptEngine's behavior to either yours or to mine. You agree?
Hide
Permalink
blackdrag blackdrag added a comment - 28/Aug/09 10:42 AM

I can't agree, since letting the class being returned means the language must have a concept of a class. Anything we specify here would be specific to Groovy and only Groovy.

Show
blackdrag blackdrag added a comment - 28/Aug/09 10:42 AM I can't agree, since letting the class being returned means the language must have a concept of a class. Anything we specify here would be specific to Groovy and only Groovy.
Hide
Permalink
Albert Kurucz added a comment - 28/Aug/09 4:22 PM

I agree that part: JSR223 should not allow those Engines to return a class which has no such concept as Class.
But how about the others?

Show
Albert Kurucz added a comment - 28/Aug/09 4:22 PM I agree that part: JSR223 should not allow those Engines to return a class which has no such concept as Class. But how about the others?
Hide
Permalink
blackdrag blackdrag added a comment - 28/Aug/09 5:27 PM

You got me wrong. I said the JSR223 spec cannot require returning a class, because there might be no concept of a class. Therefore it is a language or script engine decision. If you try to execute your BAR script using the groovy command on the command line, then it won't work too. Doing it different for the script engine would mean to have it different than GroovyShell and other places.

Show
blackdrag blackdrag added a comment - 28/Aug/09 5:27 PM You got me wrong. I said the JSR223 spec cannot require returning a class, because there might be no concept of a class. Therefore it is a language or script engine decision. If you try to execute your BAR script using the groovy command on the command line, then it won't work too. Doing it different for the script engine would mean to have it different than GroovyShell and other places.

People

  • Assignee:
    Guillaume Laforge
    Reporter:
    Albert Kurucz
Vote (0)
Watch (1)

Dates

  • Created:
    27/Aug/09 2:30 PM
    Updated:
    08/Oct/09 10:37 AM
    Resolved:
    08/Oct/09 10:37 AM
  • Atlassian JIRA (v5.0.4#731-sha1:3aa7374)
  • Report a problem
  • Powered by a free Atlassian JIRA open source license for Codehaus. Try JIRA - bug tracking software for your team.