iteye_14503
2009-05-12 16:50
浏览 228
已采纳

groovy解析的类实例序列化后无法readObject

package com.cmbchina.cc.rule.script;

import groovy.lang.Binding;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyShell;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class InvokeGroovy {
public static void main(String[] args) {

// Binding binding = new Binding();
// MerInfo foo = new MerInfo();
// foo.setAge(21);
// binding.setVariable("foo",foo);
// GroovyShell shell = new GroovyShell(binding);
//
// Object value = shell.evaluate("println '你好啊';if(foo.getAge() > 20){foo.setName('我靠');}");
// foo = (MerInfo)binding.getVariable("foo");
// System.out.println(foo.getName());
ClassLoader cl = new InvokeGroovy().getClass().getClassLoader();

     GroovyClassLoader groovyCl = new GroovyClassLoader(cl);  

     try {  
         StringBuffer sb = new StringBuffer("import com.cmbchina.cc.rule.script.IExecutor;\n");
         sb.append("import java.io.Serializable;\n");
         sb.append(" class Foo implements IExecutor,Serializable { \n");
         sb.append(" public Serializable execute() {  ");
         sb.append("println 'Hello World!';");
         sb.append("int x = 20000;");
         sb.append("if(x>10)");
         sb.append("return x;}  }");

         Class groovyClass = groovyCl.parseClass(sb.toString());  


         IExecutor foo = (IExecutor) groovyClass.newInstance();  

         writeObject(foo,"foo.bin");


         IExecutor foo2 = (IExecutor) getObject("foo.bin");
         System.out.println(foo2.execute());  

     } catch (Exception e) {  

         e.printStackTrace();  

     }  

 }  

 public static void writeObject(Object obj,String fileName){
        ObjectOutputStream oOut;
        try {

            oOut = new ObjectOutputStream(new FileOutputStream(fileName));
            oOut.writeObject(obj);

        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }       
    }
 public static Object getObject(String fileName){
        try {
            ObjectInputStream oIn = new ObjectInputStream(new FileInputStream(fileName));
            Object obj= oIn.readObject();
            return obj;
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        return null;
    }

}

java.lang.ClassNotFoundException: Foo
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:242)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:585)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1544)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1466)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1699)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
at com.cmbchina.cc.rule.script.InvokeGroovy.getObject(InvokeGroovy.java:76)
at com.cmbchina.cc.rule.script.InvokeGroovy.main(InvokeGroovy.java:47)
java.lang.NullPointerException
at com.cmbchina.cc.rule.script.InvokeGroovy.main(InvokeGroovy.java:48)
如何将序列化后的groovy类实例提取出来?我这样做的目的是想直接使用groovy生成的实例,提高效率。
该问题我想可能是classloader找不到foo的定义,因为它是在groovy里定义的,我想问如何在classloader里将foo转载进来?
[b]问题补充:[/b]
上述方法可以解决classnotfound的问题
但是还有个重要的问题,
我的初衷是序列化groovy生成的对象,然后用的时候再load进系统,节省groovy直接从文本解析的时间。现在我想要load生成的groovy对象时,必须拥有原来解析对象的groovyClassLoader引用,但是我没有办法拿到这个引用,classloader不支持序列化啊,how should i do?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • lggegegmail 2009-05-12 18:00
    已采纳

    或者你可以写自己的ObjectInputStream

    [code="java"]public class CustomObjectInputStream extends ObjectInputStream {
    ClassLoader customLoader;

    public CustomObjectInputStream ( InputStream in, ClassLoader loader ) throws IOException, SecurityException {
        super( in );
        customLoader= loader;
    }
    
    protected Class resolveClass( ObjectStreamClass v ) throws IOException, ClassNotFoundException {
        if ( customLoader == null )
            return super.resolveClass( v );
        else
            return Class.forName( v.getName(), true, customLoader);
    }
    

    }
    [/code]

    点赞 评论
  • lggegegmail 2009-05-12 17:50

    你可以试下

    [code="java"]
    // 先用groovyClassLoader替换当前的classLoader
    Thread.currentThread().setContextClassLoader(groovyClassLoader);
    ObjectInputStream oIn = new ObjectInputStream(new FileInputStream(fileName));
    Object obj= oIn.readObject();
    // 再把原来的classLoader放回去
    Thread.currentThread().setContextClassLoader(currentClassLoader);
    [/code]

    点赞 评论

相关推荐 更多相似问题