Skip to Main Content

Java Programming

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!

Custom class loader for static classes without reflection

807603Dec 17 2007 — edited Dec 17 2007
Extends thread http://forum.java.sun.com/thread.jspa?threadID=5246791&tstart=15 in order to give away more duke points.

Is it possible to load a static object with a custom class loader that makes calls to this object without reflection?

Some code:
package tests.classloader;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Hashtable;

public class UnloadingTest {
	public static void main(String[] args) throws Exception {
		CustomClassLoader test = new CustomClassLoader();
		
        Object o = test.loadClass("tests.classloader.Singleton").newInstance();
        
        System.out.println("Instantiated Singleton: " + o.getClass());
        System.out.println("Instantiated Singleton classloader: " + o.getClass().getClassLoader());        
        System.out.println("Static Singleton outside singleton constructor:" + Singleton.class.getClassLoader());
	}
}

class CustomClassLoader extends ClassLoader {
	private Hashtable<String, Class<?>> classes = new Hashtable<String, Class<?>>();
	
    public CustomClassLoader(){
        super(CustomClassLoader.class.getClassLoader());    	
    }
  
    public Class loadClass(String className) throws ClassNotFoundException {
         return findClass(className);
    }
 
    public Class findClass(String className){
        byte classByte[];
        Class result=null;
        result = (Class)classes.get(className);
        if(result != null){
            return result;
        }
        
        // since findClass is overloaded we'll get a recursive
        // call from system class loader here
        if (className.indexOf("java") >= 0) {
	        try{
	        	result = findSystemClass(className);
	        	classes.put(className,result);
	            return result;
	        }catch(Exception e){
	        }
        }
        
        try{
           String classPath =  File.separatorChar +   ((String)ClassLoader.getSystemResource(className.replace('.',File.separatorChar)+".class").getFile()).substring(1);
           classByte = loadClassData(classPath);
            result = defineClass(className,classByte,0,classByte.length,null);
            classes.put(className,result);
            return result;
        }catch(Exception e){
            return null;
        } 
    }
 
    private byte[] loadClassData(String className) throws IOException {
 
        File f ;
        f = new File(className);
        int size = (int)f.length();
        byte buff[] = new byte[size];
        FileInputStream fis = new FileInputStream(f);
        DataInputStream dis = new DataInputStream(fis);
        dis.readFully(buff);
        dis.close();
        return buff;
    }    
}
And the separate singleton class:
package tests.classloader;

public class Singleton {
	public static boolean loaded = false;
	
	private static Singleton s;
	
	private static int accesses = 0;
	
	public Singleton() {
		System.out.println("Singleton constructor: " + Singleton.class.getClassLoader());		
		if (loaded) {
			System.out.println("Already loaded.");
		}
		loaded = true;
	}
	
	public static Singleton getInstance() {
		if (!loaded) {
			s = new Singleton();
		}
		return s;
	}
	
	public static int getAccesses() {
		return accesses++;		
	}
	
	public static void dispose() {
		loaded = false;
		s = null;
	}
}
The output is:
Singleton constructor: tests.classloader.CustomClassLoader@ca318a
Instantiated Singleton: class tests.classloader.Singleton
Instantiated Singleton classloader: tests.classloader.CustomClassLoader@ca318a
Static Singleton outside singleton constructor:sun.misc.Launcher$AppClassLoader@a9c85c
But I'd like the last line of output to be:
Static Singleton outside singleton constructor: tests.classloader.CustomClassLoader@ca318a
Which seems to be the case in the Singleton constructor.

Is this possible?

Regards
rimu
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jan 14 2008
Added on Dec 17 2007
4 comments
628 views