Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy Binding: Cannot cast object with class 'custompackage.CustomClass' to class 'custompackage.CustomClass'

Tags:

groovy

Using Groovy Binding to execute scripts from a main controller and attempting to pass a custom object, I get the error mentioned in the title.

Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'custompackage.CustomClass@60099951' with class 'custompackage.CustomClass' to class 'custompackage.CustomClass'

Here's the relevant code:

// Controller.groovy
import custompackage.CustomClass
CustomClass test = new CustomClass()

def binding = new Binding()
def engine = new GroovyScriptEngine('./src')

binding.setProperty("test", test)

engine.run("CustomScript.groovy", binding)

The file being run with above:

// CustomScript.groovy
import custompackage.CustomClass
CustomClass t 

if(!binding.variables.containsKey("test")){
    t = new CustomClass()
} else {        
    t = test
}

I'm defining the CustomClass t at the beginning for the purpose of autocomplete in my IDE. When running as def t it works fine.

I know the object is being passed correctly, due to the exception (and further printing of the object)

The error occurs on t = test

Why is Groovy trying to cast an object of the same type to it's type, and then failing to do so? And is there a fix that will still allow me to keep the statically typed t?

Thanks!

like image 895
Devin H. Avatar asked Oct 31 '22 14:10

Devin H.


1 Answers

It seems custompackage.CustomClass in Controller.groovy is not the same as in CustomScript.groovy.

I checked the class instances in CustomScript.groovy with the debugger and found something interesting:

def a = CustomClass.class // Debugger: a={Class@1499} "class custompackage.CustomClass"
def b = test.class        // Debugger: b={Class@1187} "class custompackage.CustomClass"

While when using GroovyShell instead of GroovyScriptEngine in Controller.groovy I get:

def a = CustomClass.class // Debugger: a={Class@1185} "class custompackage.CustomClass"
def b = test.class        // Debugger: b={Class@1185} "class custompackage.CustomClass"

and the assignment t = test works without error.

The Controller.groovy file using GroovyShell looks like this:

// Controller.groovy
import custompackage.CustomClass
CustomClass test = new CustomClass()

def binding = new Binding()
def shell = new GroovyShell(binding)

binding.setProperty("test", test)

shell.evaluate(new File("CustomScript.groovy"))

I checked the documentation of GroovyScriptEngine and found a constructor which takes a ClassLoader as argument. Maybe that's the way to go but I don't know for sure.

like image 124
Emanuel Seidinger Avatar answered Nov 23 '22 05:11

Emanuel Seidinger