Skip to Main Content

New to Java

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Using a classloader with a byte array then casting to superclass?

805433Oct 14 2010 — edited Oct 18 2010
Basically im writing a script system which uses class files as scripts and each class file overrides the Script superclass.

However, when i try and cast it when loading it's giving me the error;

"Cannot be cast to Script".

Here are my classes;

ClassLoaderSub.java
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.Hashtable;

public class ClassLoaderSub extends ClassLoader {

    public Hashtable loadedClasses = new Hashtable();
    public ProtectionDomain protectionDomain;
    public ScriptUnpacker scriptUnpacker;

    public ClassLoaderSub() {
        CodeSource codeSource = new CodeSource(null, (Certificate[]) null);
        Permissions permissions = new Permissions();
        permissions.add(new AllPermission());
        protectionDomain = new ProtectionDomain(codeSource, permissions);
    }

    public synchronized Class loadClass(String className, boolean resolve) throws ClassNotFoundException {
	System.out.println(className);
        Class rsClass = (Class) loadedClasses.get(className);
        if (rsClass != null) {
            return rsClass;
        }
        if (scriptUnpacker != null) {
            byte[] classBytes = scriptUnpacker.getClassBytes(className);
            if (classBytes != null) {
                rsClass = defineClass(className, classBytes, 0, classBytes.length, protectionDomain);
                if (resolve) {
                    resolveClass(rsClass);
                }
                loadedClasses.put(className, rsClass);
                return rsClass;
            }
        }
        return super.findSystemClass(className);
    }
}
Script.java
public abstract class Script {

	public abstract void method1();

	public abstract void method2();

}
ScriptUnpacker.java
import java.io.*;
import java.util.*;

public class ScriptUnpacker {

    public Hashtable classBytes = new Hashtable();

    public ScriptUnpacker()
    {
        unpack();
    }

    public void unpack()
    {
        try {
            File[] scripts = new File("./scripts").listFiles();
            for (File f : scripts)
            {
                if(!f.getName().endsWith(".class"))
                    continue;
                String entryName = f.getName().substring(0, f.getName().length() - 6);
                byte[] buffer = new byte[(int) f.length()];
                DataInputStream reader = new DataInputStream(new FileInputStream(f));
                reader.readFully(buffer);
                reader.close();
                classBytes.put(entryName, buffer);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public byte[] getClassBytes(String className)
    {
        return (byte[]) classBytes.remove(className);
    }

}
One.java - Test script
public class One extends Script {

    public One()
    {
        System.out.println("Loaded one.");
    }

    @Override
    public void method1()
    {
        System.out.println("method 1");
    }

    @Override
    public void method2()
    {
        System.out.println("method 2");
    }

}
And finally my main class;

Main.java
public class Main {

	public static void main(String[] args)
	{
		try {
			ClassLoaderSub cls = new ClassLoaderSub();
			cls.scriptUnpacker = new ScriptUnpacker();
			Class script = cls.loadClass("One");
			Script sc = (Script) script.newInstance();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

}
Thanks for any help.
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Nov 15 2010
Added on Oct 14 2010
10 comments
497 views