2016-07-17 4 views
3

JavaとGroovyの間でオブジェクトをScriptEngineで渡そうとしました。その結果、いくつかのロジックをGroovyスクリプトにデカップリングできます。しかし、私は2つの問題に出会った:`ScriptEngine`を使用したケースオブジェクトの場合、ClassCastException`

  1. オブジェクトをgroovyスクリプトに渡すことはできません。
  2. groovyスクリプトからオブジェクトを取得できません。ここで

コードです:

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); 

出力は以下のとおりです。

アウト期待
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) 

putは9となり、Outputが返されます。

+1

通常、「XはXにキャストできません」というのは、2つの異なるクラスローダーが関係するClassLoaderの問題を示しているため、同じクラス名を持っていても2つのインスタンスが同じではありません。この場合、私はそれが当てはまるかどうかはわかりませんが、エラーの別の正当な理由は考えられません。 Groovyに独自のクラスローダー階層がないことを再確認してください。 –

+0

右私はそれを確認します。それが正しいとすれば、どうすればこの問題を解決できますか?または、オブジェクトではなく文字列(json形式のデータ)でデータを交換する必要がありますか? – Xiaokun

+0

申し訳ありませんが、Groovyはまったく分かりません。 「groovy classloading」でGoogle検索を行うと、クラスローディングを変更する方法について議論する「面白い」ヒットがたくさんあるので、これは既知の問題のようです。私はあなたが解決策を見つけることができるかどうかを確認するためにGoogleの結果をあなたの方法を作業することをお勧めします。 –

答えて

1

Groovyクラスローダーがスクリプトをコンパイルすると、クラスtest.testScriptEngine.Outputが作成されます。

ただし、スクリプトから生成されたクラスは、Javaコードからコンパイルされたクラスと同じではありません。たとえバイトコードが等しいとしても、異なるクラスローダーはそれらを異なるクラスにします。

+0

また、彼をもう少し手助けするには:スクリプトからクラスを削除して、javaでのみ定義されるようにします。これらはスクリプトからまだアクセス可能です。 –

関連する問題