[4198] in java-interest

home help back first fref pref prev next nref lref last post

Re: (Fwd) More class loader info.

daemon@ATHENA.MIT.EDU (neudeck.arthur@ch.swissbank.com)
Wed Dec 13 11:30:47 1995

From: neudeck.arthur@ch.swissbank.com
Date: Wed, 13 Dec 1995 15:33:56 +0100
To: pambrose@weblogic.com
Cc: neudeca@ch.swissbank.com, java-interest@java.sun.com

----------
X-Sun-Data-Type: text
X-Sun-Data-Description: text
X-Sun-Data-Name: text
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 71

Hoi ...

> Here is a routine that I use to plugins for a server:
> 
>   public synchronized Class loadClass(String name, boolean resolve)
>     throws ClassNotFoundException
>   {
>     try {
>       System.out.println("PluginLoader loading: " + name);
> 
>       if (name.startsWith("weblogic.") || 
>           name.startsWith("java.")     ||
>           name.startsWith("sun."))
>         return findSystemClass(name);
> 
>       if (PluginLoader.classes.containsKey(name)) {
>         System.out.println("Using cached value " + name);
>         return (Class)PluginLoader.classes.get(name);
>       }
> 
>       byte data[] = loadClassFromFile(name);
> 
>       Class cl = defineClass(data, 0, data.length);
> 
>       resolveClass(cl); 
>    
>       PluginLoader.classes.put(name, cl);
>       return cl;
>     }
>     catch (Exception e) 
>       throw new ClassNotFoundException(e.getClass().getName() + " - " + e.getMessage());
>   }
> }
>  
> You can see I am also saving the defs in a hashtable.
> If your code is doing all the above, then the only other 
> thing I can think of is: do you have a null constructor 
> explicitly defined for the class you are loading.
> Also, do you have the correct constructors for each of the 
> parent classes of the lowest-level object being
> instantiated?
> 
> Paul

Sorry for replying that late, but I had to try and try and try and ....
Fortunatley my research has come to a positive end: My own ClassLoader is
doing his work almost fine.

There have been several problems, that I discovered:

	1.)	You'll get an "IllegalAccessError" whenever you try to instantiate a non
		"public class". Why is it that way? Don't ask me ....

	2.)	A big problem still existing is the following matter of fact:
		A oncely loaded base class within your own ClassLoader will never be found
		from the system class loader. You'll get a "ClassDefNotFoundError" or anything
		else for this class.
		Probable solutions:	Perhaps you can set your own ClassLoader as the default
					one that covers the default one and more.
					But how???

If you or somebody else did find out any solutions or had to add something, you could
write me. I will collect any info and summarize.

Thanx again for your help.

Have a nice day,
	Arthy

BTW: 	The final result for all those people who have
	the same problems as I have/ had is attached.
----------
X-Sun-Data-Type: default
X-Sun-Data-Description: default
X-Sun-Data-Name: ManagerClassLoader.java
X-Sun-Charset: us-ascii
X-Sun-Content-Lines: 172

import java.util.Hashtable;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.FileInputStream;
import java.util.Vector;

/* ******************************************************************** */
/* Classname:	ManagerClassLoader					*/
/* ******************************************************************** */
/**
 * This class extends the default mechanism for loading classes. This is
 * is done via three different ways: First a cache will be searched wether
 * the class already has been loaded or not. Second the default mechanism 
 * in the java environment will be used. If this didn't succeed, the own
 * extension would be invoked. This extension is represented by a loading
 * method that looks at a certain directory on the local file system.
 *
 * @version:	0.1, 27. Oct 1995
 * @version:	0.2, 07. Dez 1995
 * @version:	0.3, 13. Dez 1995
 * @author:	Arthur Neudeck, SYSTOR AG
 */
/* ******************************************************************** */
/* Created:	10/27/95						*/
/* ******************************************************************** */
public final class ManagerClassLoader extends ClassLoader{
 // ---------- -
 // attributes -
 // ---------- -
 private	TOLogging	loggingManager;		// default error out
 private	Hashtable	classCache;		// avoids double load of
							// one class (=cache)
 private	Hashtable	collocatedClasses;	// (not used yet)

/* -------------------------------------------------------------------- */
/* Method:	ManagerClassLoader()					*/
/* -------------------------------------------------------------------- */
/**
 * default constructor.
 *
 * @param	inLoggingManager	default output for warnings, 
 *					errors, infos and anything else
 */
/* -------------------------------------------------------------------- */
 public ManagerClassLoader(TOLogging inLoggingManager){
	super();
	loggingManager		= inLoggingManager;
	classCache		= new Hashtable();
	collocatedClasses	= new Hashtable();
 }

/* -------------------------------------------------------------------- */
/* Method:	loadClassDataFromFile()					*/
/* -------------------------------------------------------------------- */
/**
 * this method loads the binary code of a class from the local file
 * system. It looks at the "../to" directory.
 *
 * @param	inClassName	real name of the class
 * @return	the binary code as a an array of bytes
 */
/* -------------------------------------------------------------------- */
 private byte[] loadClassDataFromFile(String inClassName)
		throws FileNotFoundException{
	// ---------------- -
	// local attributes -
	// ---------------- -
	byte	classData[];
	long	dataSize;
	File	classFile	= new File("../to/"+inClassName+".class");

	// ------------------- -
	// file does not exist -
	// ------------------- -
	if(classFile.exists()==false) throw new FileNotFoundException();

	// ---------------------------------------- -
	// open/close file and read the byte stream -
	// ---------------------------------------- -
	try{
	FileInputStream fileStream = new FileInputStream(inClassName);
	classData	= new byte[fileStream.available()];
	fileStream.read(classData);
	fileStream.close();
	return classData;

	// ---------- -
	// read error -
	// ---------- -
	} catch (IOException readError){
		loggingManager.logError(this,"Couldn't read data from <"
			+inClassName+">");
		return null;
	}
}

/* -------------------------------------------------------------------- */
/* Method:	loadClass()						*/
/* -------------------------------------------------------------------- */
/**
 * method that has to be implemented because of abstract method in
 * super class "ClassLoader". It returns the executable class.
 *
 * @param	inClassName	real name of the class
 * @param	resolve		should super and contained classes
 *				immediately be loaded by this loader?
 * @return	the instantiateable class
 */
/* -------------------------------------------------------------------- */
 public synchronized Class loadClass(	String	inClassName,
					boolean	resolve){
	// ------------------------ -
	// get the class from cache -
	// ------------------------ -
	Class	newClass	= (Class)classCache.get(inClassName);
	
	// ------------------------------------------------------------ -
	// load the class via default mechanism within java environment -
	// ------------------------------------------------------------ -
	loggingManager.logInfo("Loading object <"+className+">");
	if( newClass == null){
		try{
		newClass = findSystemClass(inClassName);
		classCache.put(inClassName,newClass);
		className = new String(inClassName);
		System.out.println("Default:"+inClassName);

		// class not found will be unhandled because later the	-
		// own method will be called				-
		// ---------------------------------------------------- -
		} catch (ClassNotFoundException noClassDefFound);
		}//if

	// --------------------------------- -
	// load the class via own mechanism  -
	// --------------------------------- -
	if(newClass == null){
		try{
		byte	data[]	= loadClassDataFromFile(inClassName);
		newClass	= defineClass(data,0,data.length);
		classCache.put(inClassName,newClass);
		if(resolve == true) resolveClass(newClass);
		System.out.println("Mine:"+className);			
		}catch (FileNotFoundException e){
			loggingManager.logError(this,"<"+inClassName+
				"> is not a class ...");

		// class that can not be loaded with this loader -
		// --------------------------------------------- -
		} catch (ClassFormatError unknownFormat){
			loggingManager.logError(this,"<"+inClassName+
				"> is not a class ...");

		// ---------------------------- -
		// catch any uncaught exception -
		// ---------------------------- -
		} catch (Exception anyException){
			System.out.println(anyException);
		}//catch
		}//if

 // ----------------------------------------------- -
 // return either null or the instantiateable class -
 // ----------------------------------------------- -
 return newClass;
 }
}

/* *** */
/* END */
/* *** */
-
This message was sent to the java-interest mailing list
Info: send 'help' to java-interest-request@java.sun.com

home help back first fref pref prev next nref lref last post