Serialisierung + ClassLoader

kurwajebana

Grünschnabel
Hallo,

ich möchte über Netzwerk ein serialisiertes Object einer Klasse (Test) als Datei, und die dazugehörige .class Datei schicken. Eine Klasse Load soll auf einem entfernten Rechner die .class Datei laden sowie das Serialisierte Object der Klasse, deserialisieren (alles ohne RMI!). Das Serialisieren des Objectes und schicken der .class klappt, die Frage ist, wie schreibe ich mir den ClassLoader dazu?

Klasse Test:
Code:
public class Test implements Serializable {

    public int version;
    
	private static final long serialVersionUID = 1L;
	
	public Test(int version) {
		this.version = version;
	}
	
	public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("D:\\test\\Test.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        Test ts = new Test(100);
        oos.writeObject(ts);
        oos.flush();
        oos.close();
	}
}


Klasse Load:
Code:
public class Load {
	

	  public static void main( String[] args ) throws Exception   {    
		  Loads lc = new Load();
		  URL url = new File("D:\\workspace\\Test\\bin").toURI().toURL(); 
		  ClassLoader cl = new URLClassLoader(new URL[]{ url } );
		  Class<?> c = cl.loadClass("test.Test");
		  
		  //c.newInstance();

		  FileInputStream fis = new FileInputStream("D:\\test\\Test.ser");
	                    ObjectInputStream oin = new ObjectInputStream(fis);
	                    Load lo = (Load) oin.readObject(); //Fehler: ClassNotFoundException

	  } 
}

Danke schonmal für eure Hilfe!
 
Hallo,

dazu gibts wie immer mehrere Möglichkeiten... hier mal exemplarisch:

eine Möglichkeit ist von ObjectInputStream abzuleiten und die resolveClass Methode zu überschreiben.
eine wetere wäre die neuen Klassen dynamisch in den bestehenden Classpath zu legen.

Java:
package de.tutorials.training;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class RemoteClassLoadingExample {

    static String basePath = "/home/tom/Desktop/workspaces/sts/de.tutorials.training.gwt";
    
    public static void main(String[] args) throws Exception {
        method0();
        method1();
    }
    
    private static void method0() throws Exception{
        ClassLoader classLoader = new URLClassLoader(new URL[]{new File(basePath + "/war/WEB-INF/classes").toURI().toURL()});
        ObjectInputStream ois = new ClassLoaderAwareObjectInputStream(classLoader, new FileInputStream(basePath + "/stuff.ser"));
        Object o = ois.readObject();
        System.out.println(o);
    }

    static class ClassLoaderAwareObjectInputStream extends ObjectInputStream {

        protected ClassLoader classLoader;
        
        public ClassLoaderAwareObjectInputStream(ClassLoader classLoader, InputStream in) throws IOException, SecurityException {
            super(in);
            this.classLoader = classLoader;
        }
        
        @Override
        protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
            String className = desc.getName();
            return Class.forName(className,false,classLoader);
        }

    }

    private static void method1() throws Exception {
        
        URLClassLoader classLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
        addToClassPathOf(classLoader, new File(basePath + "/war/WEB-INF/classes").toURI().toURL());

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(basePath + "/stuff.ser"));
        Object o = ois.readObject();
        System.out.println(o);
    }

    static void addToClassPathOf(URLClassLoader urlClassLoader, URL... urls) {
        try {
            Method addUrlMethod = URLClassLoader.class.getDeclaredMethod(
                    "addURL", URL.class);
            addUrlMethod.setAccessible(true);
            for (URL url : urls) {
                try {
                    addUrlMethod.invoke(urlClassLoader, url);
                } catch (Exception e) {
                    System.err.println(String.format(
                            "could not add: %s to classpath", url));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Java:
package de.tutorials.training.client;

import java.io.Serializable;

public class Stuff implements Serializable{
    private static final long serialVersionUID = 1L;
    
    protected String id;
    protected String name;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Stuff [id=" + id + ", name=" + name + "]";
    }    
}

Java:
package de.tutorials.training.client;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class Serializer {
    public static void main(String[] args) throws Exception{
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("stuff.ser"));
        Stuff stuff = new Stuff();
        stuff.setId("1234");
        stuff.setName("ABC");
        oos.writeObject(stuff);
        oos.close();
    }
}
Gruß Tom
 
Zurück