2014-11-05 28 views
0

我想在groovy中動態地創建一個可序列化的接口實現,它可以通過網絡發送,它可以被反序列化並用args執行。我使用map創建了匿名接口實現,但在序列化時失敗。沒有類定義的Groovy序列化

gcloader = new ​GroovyClassLoade​r() 
script = "class X { public def x = [call: {y -> y+1}] as MyCallable }"​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 
gclass = gcloader.parseClass(script) 
x = gclass.newInstance().x​​ 
// serialzing x fails 

我不知道,如果一個Groovy閉包被編譯爲一個隨機的類名,這將使它不可能,即使它被序列化反序列化。有沒有辦法做到這一點?

+2

什麼是例外? – 2014-11-05 14:39:13

+0

我使用的是https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/SerializationUtils.html,奇怪的是我得到java.io.NotSerializableException:X ie頂級類:( – FUD 2014-11-05 14:42:56

+0

其實如果我做「X實現SER ..」然後我能夠序列化它,但在反序列化我得到java.lang.ClassNotFoundException:X $ _closure1,這是有道理的。所以這可以通過一些其他的詭計? – FUD 2014-11-05 14:45:48

回答

0

下面是一段代碼,可能會有所幫助:

import groovy.lang.GroovyClassLoader 

def gcLoader = new GroovyClassLoader() 
def script = """ 
class X implements Serializable { 
    public def x = [ 
     call: { y -> y + 1 } 
    ] 
}""" 
def cls = gcLoader.parseClass(script) 
def inst = cls.newInstance().x 

def baos = new ByteArrayOutputStream() 
def oos = new ObjectOutputStream(baos) 

oos.writeObject(inst) 

def serialized = baos.toByteArray() 

def bais = new ByteArrayInputStream(serialized) 
def ois = new CustomObjectInputStream(bais, gcLoader) 
inst = ois.readObject() 

assert 2 == inst.call(1) 

public class CustomObjectInputStream extends ObjectInputStream { 
    private ClassLoader classLoader 

    public CustomObjectInputStream(InputStream ins, ClassLoader classLoader) throws IOException { 
     super(ins) 
     this.classLoader = classLoader 
    } 

    protected Class<?> resolveClass(ObjectStreamClass desc) throws ClassNotFoundException { 
     return Class.forName(desc.getName(), false, classLoader) 
    } 
} 

基本上,你需要的ObjectInputStream實例定製ClassLoader

+0

謝謝@Opal,但你認爲這會工作,當我通過線路發送序列化的對象?另一方面,即使我有一個類加載器,它也不會有爲序列化定義的類(例如閉包) – FUD 2014-11-06 03:42:19

+0

不知道真的,你需要做進一步的調查。 – Opal 2014-11-06 03:54:29

0

根據我自己的有限研究,我得出的結論是,在jvm中沒有標準/流行的庫,它可以像python一樣醃製代碼,這是我主要以後的要求。有一些方法可以通過URL類加載器來完成,但有一些固有的複雜性。我最終只是簡單地發送代碼字符串並在需要時在多臺機器上重新編譯它。

相關問題