The link to mindprod.com says you can use defineClass on
java.lang.ClassLoader, but that method is protected. Did I read
something wrong somwhere? Or is the link saying you should call it
through reflection after calling method.setAccessible(true)?
Here is one I wrote a long time ago in the days of Netscape 4. The key
is to get at a protected method, you must extend its class. I found
this is my EXPER directory, so it is not production code, but a
prototype experiment. But it might be enough to give you the idea.
import java.io.File;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.zip.ZipFile;
/**
* ClassLoader to let us find class files preinstalled in
*
C:\Program_Files\Netscape\Communicator\program\java\classes\pcclock.jar
*/
public class LocalClassLoader extends ClassLoader
{
private Hashtable cache = new Hashtable();
/**
* This is a simple version for external clients since they
* will always want the class resolved before it is returned
* to them.
*/
public Class loadClass(String className) throws
ClassNotFoundException {
return(loadClass(className, true));
}
/**
* get bytes for class from a specific jar file.
*/
private byte[] loadClassData(String name) throws
ClassNotFoundException{
String jarname =
"\\Program_Files\\Netscape\\Communicator\\program\\java\\classes\\pcclock.jar";
File jar = null;
InputStream is = null;
ZipFile zip = null;
try
{
jar = new File("C:" + jarname);
if ( !jar.exists() )
{
jar = new File("D:" + jarname);
}
if ( !jar.exists() )
{
throw new java.lang.ClassNotFoundException("missing jar "
+ jarname);
}
zip = new ZipFile(jar);
if ( zip == null )
{
throw new java.lang.ClassNotFoundException("corrupt jar "
+ jarname);
}
is = zip.getInputStream(zip.getEntry(name));
if ( is == null )
{
throw new java.lang.ClassNotFoundException("class " + name
+ " not found in jar " + jarname);
}
int bytesToRead = is.available();
byte[] b = new byte[bytesToRead];
int bytesRead = is.read(b);
if ( bytesRead != bytesToRead )
{
throw new java.lang.ClassNotFoundException("class " + name
+ " corrupt in jar " + jarname);
}
if ( is != null )
{
is.close();
}
if ( zip != null )
{
zip.close();
}
return b;
}
catch ( java.io.IOException e )
{
throw new java.lang.ClassNotFoundException("corrupt jar " +
jarname);
}
} // end loadClassData
/**
* load class from
*
C:\Program_Files\Netscape\Communicator\program\java\classes\pcclock.jar
* @param className fully qualified name of class to load.
* @param true if you want the class resolved, ready to use.
* @return class object.
*/
protected synchronized Class loadClass(String className,
boolean resolve)
throws ClassNotFoundException
{
Class c = (Class)cache.get(className);
if ( c == null )
{
/* Check with the primordial class loader */
try
{
c = super.findSystemClass(className);
}
catch ( ClassNotFoundException e )
{
}
if ( c == null )
{
// primordial did not have it, look in jar.
// loadClassData will throw ClassNotFoundException if it
does not have it.
byte[] data = loadClassData(className);
c = defineClass(data, 0, data.length);
cache.put(className, c);
}
}
if ( resolve )
{
// prepare class for use
resolveClass(c);
}
return c;
} //end loadClass
} // end LocalClassLoader