Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`ClassCastException` when case object with `ScriptEngine`

I try to pass object between Java and Groovy with ScriptEngine so that I can decouple some logic into groovy script. But I met two problems:

  1. cannot pass object to groovy script.
  2. cannot obtain object from groovy script.

Here are the codes:

App.java

package test.testScriptEngine;

import java.io.FileNotFoundException;
import java.io.FileReader;

import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;


public class App {
    public static void main(String[] args) throws Exception {
        App app=new App();
        Output out=app.runSript();
        System.out.println(out.a);
    }

    public Output runSript() throws ScriptException, FileNotFoundException {

        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("groovy");
        Bindings binding = engine.createBindings();

        Input input=new Input(4,5);
        binding.put("input", input);

        FileReader reader = new FileReader("src/main/resources/test.groovy");
        Object obj = engine.eval(reader, binding);

        return (Output) obj;
    }

}
class Input{
    public Input(int i, int j) {
        this.a=i;
        this.b=j;
    }
    int a=1;
    int b=2;
}
class Output{
    int a=1;
}

test.groovy

package test.testScriptEngine;

class Input{
        int a=1;
        int b=2;
    Input(int a,int b){
        this.a=a;
        this.b=b;
    }
}
class Output{
        int a=1;
}

Output cal(Input input){
    Output out= new Output();
    out.a=input.a+input.b;
    println(out.a);
    return out;
}
Input input=new Input(2,3);
return cal(input);

Output are:

5
Exception in thread "main" java.lang.ClassCastException: test.testScriptEngine.Output cannot be cast to test.testScriptEngine.Output
    at test.testScriptEngine.App.runSript(App.java:31)
    at test.testScriptEngine.App.main(App.java:15)

Expected output should be 9 and Output should be returned.

like image 443
Xiaokun Avatar asked May 20 '26 08:05

Xiaokun


1 Answers

When the Groovy class loader compiles your script it creates the class test.testScriptEngine.Output.

However, the class generated from the script is not the same as the test.testScriptEngine.Output class compiled from the Java code. Even if their bytecode would be equal, the different class loaders would make them different classes.

like image 79
aventurin Avatar answered May 21 '26 22:05

aventurin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!