Issue Details (XML | Word | Printable)

Key: GROOVY-2137
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Critical Critical
Assignee: Jochen Theodorou
Reporter: Jörg Staudemeyer
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
groovy

Enum class does not load

Created: 23/Sep/07 04:38 PM   Updated: 11/Oct/07 07:48 PM   Resolved: 11/Oct/07 07:48 PM
Return to search
Component/s: None
Affects Version/s: 1.1-beta-3
Fix Version/s: 1.1-rc-1

Time Tracking:
Not Specified

Environment: JDK 1.5.0 / JDK 1.6.0; Windows Vista


 Description  « Hide

Looks as if they compile properly, but lead to an error at load time. Groovysh session transcript follows.

Groovy Shell (1.1-beta-3, JVM: 1.6.0_01-b06)
Type 'go' to execute statements; Type 'help' for more information.
groovy> enum E {A, B, C}
groovy> go
ERROR: groovy.lang.GroovyRuntimeException: Failed to create Script instance for class: class E. Reason: java.lang.InstantiationException: E
groovy.lang.GroovyRuntimeException: Failed to create Script instance for class: class E. Reason: java.lang.InstantiationException: E
at org.codehaus.groovy.runtime.InvokerHelper.createScript(InvokerHelper.java:385)
at groovy.lang.GroovyShell.parse(GroovyShell.java:500)
at groovy.lang.GroovyShell.parse (GroovyShell.java:480)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:458)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:434)
at groovy.ui.InteractiveShell.run(InteractiveShell.java :289)
at groovy.ui.InteractiveShell.main(InteractiveShell.java:101)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java :39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader (GroovyStarter.java:101)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:130)
Caused by: java.lang.InstantiationException: E
at java.lang.Class.newInstance0(Class.java:340)
at java.lang.Class.newInstance(Class.java:308)
at org.codehaus.groovy.runtime.InvokerHelper.createScript(InvokerHelper.java:366)
... 12 more



Danno Ferrin added a comment - 24/Sep/07 03:56 PM - edited

The compiler returns an Enum object, whereas the InvokerHelper is expecting a Script or a GroovyObject.

I propose we return the Class object for the enum in this instance (IMHO the other sensible option being to return null). This will only be visible in scripts where the only expression is a single enum statement, so I don't think it can be tripped elsewhere accidentally.


Danno Ferrin added a comment - 24/Sep/07 04:11 PM - edited

This patch gets rid of the exception....

Index: src/main/org/codehaus/groovy/runtime/InvokerHelper.java
===================================================================
--- src/main/org/codehaus/groovy/runtime/InvokerHelper.java     (revision 8215)
+++ src/main/org/codehaus/groovy/runtime/InvokerHelper.java     (working copy)
@@ -353,7 +353,7 @@
         return invokeMethod(script, "run", EMPTY_ARGS);
     }

-    public static Script createScript(Class scriptClass, Binding context) {
+    public static Script createScript(final Class scriptClass, Binding context)
 {
         // for empty scripts
         if (scriptClass == null) {
             return new Script() {
@@ -363,11 +363,18 @@
             };
         }
         try {
-            final GroovyObject object = (GroovyObject) scriptClass.newInstance();
             Script script = null;
-            if (object instanceof Script) {
-                script = (Script) object;
+            if (Script.class.isAssignableFrom(scriptClass)) {
+                script = (Script) scriptClass.newInstance();
+            } else if (Enum.class.isAssignableFrom(scriptClass)) {
+                // return the class object...
+                script = new Script() {
+                    public Object run() {
+                        return scriptClass;
+                    }
+                };
             } else {
+                final GroovyObject object = (GroovyObject) scriptClass.newInstance();
                 // it could just be a class, so lets wrap it in a Script wrapper
                 // though the bindings will be ignored
                 script = new Script() {

But then actual attempts to use the enum result in the following exception....

groovy> enum E {A,B,C}
groovy> go
===> class E
groovy> E.A
groovy> go
ERROR: java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at Script2.class$(Script2.groovy)
at Script2.run(Script2.groovy)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:459)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:434)
at groovy.ui.InteractiveShell.run(InteractiveShell.java:289)
at groovy.ui.InteractiveShell.main(InteractiveShell.java:101)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:101)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:130)
Caused by: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '[Ljava.lang.Object;@adb1d4' with class '[Ljava.lang.Object;' to class 'E'
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:326)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:642)
at E.$INIT(Script1.groovy)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod.invoke(ReflectionMetaMethod.java:64)
at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke(MetaClassHelper.java:537)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:913)
at org.codehaus.groovy.runtime.Invoker.invokeMethod(Invoker.java:69)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:74)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:158)
at E.<clinit>(Script1.groovy)
... 14 more

(JVM 1.5.0_11-b03 Windows Vista, if it matters)

Hence the failures I didn't commit and will let the deeper language folks dig at it.


Jochen Theodorou added a comment - 24/Sep/07 04:16 PM

enums created by Groovy are implementing GroovyObject. I think the problem is more inside the static initializer.. looks like a ClassCastException.. a trivial element is missing I guess


Jochen Theodorou added a comment - 11/Oct/07 07:48 PM

the exception int the static initializer is fixed