F
Frank Rouse
Hello All,
I am trying to create my own classloader that will load a different
version of a class from a jar file. I create a new thread and subclass
URLClassloader and override the loadClass method such that it will
search in the given jar first for the class and return that.
Tracing through the execution all seems to go well. The loadClass
method returns what seems to be a valid class but when I attempt to use
the class I receive an InstantiationExeception. I have confirmed that
the URL is valid so I know that it is not an issue. I also created a
wide open java.policy file just in case it was something security related.
The relevent code is below. I'd appreciate any pointers that anyone
can give.
Cheers
****************************************
Relevent portion of thread code
****************************************
public final void run() {
URL[] codeLLocation = new URL[1];
codeLLocation[0] = codeLocation;
NewURLClassLoader loader = new NewURLClassLoader(codeLLocation);
Thread.currentThread().setContextClassLoader(loader);
Object o = null;
while (keepRunning) {
if (o == null) {
try {
System.out.println("The parent classloader = " + loader.getParent());
Class c = loader.loadClass("<full_package_name_of_object");
System.out.println("Classloader = " + c.getClassLoader());
Object o = c.newInstance(); <===== Exception here.
****************************************
Extended URLClassLoader
****************************************
package org.fhtc.jde.threadtest;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class NewURLClassLoader extends URLClassLoader {
URL[] urls;
NewURLClassLoader(URL[] inputURLS) {
super(inputURLS);
urls = inputURLS;
}
public Class findClass(String name) throws ClassNotFoundException {
byte[] b = loadClassData(name);
if (b == null) {
throw (new ClassNotFoundException());
}
Class c = super.defineClass(name, b, 0, b.length);
return c;
}
public synchronized Class loadClass(String name)
throws ClassNotFoundException {
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
try {
c = this.findClass(name);
} catch (ClassNotFoundException e) {
c = super.loadClass(name);
}
}
return c;
}
private byte[] loadClassData(String className) {
byte[] buffer = new byte[1];
String realName = className.replace('.', '/');
realName += ".class";
try {
JarFile jarFile = new JarFile(urls[0].getFile());
JarEntry entry = jarFile.getJarEntry(realName);
if (entry != null) {
buffer = new byte[(int) entry.getSize()];
BufferedInputStream is = new BufferedInputStream(jarFile
.getInputStream(entry));
is.read(buffer);
} else {
buffer = null;
}
} catch (IOException e) {
buffer = null;
}
return buffer;
}
}
I am trying to create my own classloader that will load a different
version of a class from a jar file. I create a new thread and subclass
URLClassloader and override the loadClass method such that it will
search in the given jar first for the class and return that.
Tracing through the execution all seems to go well. The loadClass
method returns what seems to be a valid class but when I attempt to use
the class I receive an InstantiationExeception. I have confirmed that
the URL is valid so I know that it is not an issue. I also created a
wide open java.policy file just in case it was something security related.
The relevent code is below. I'd appreciate any pointers that anyone
can give.
Cheers
****************************************
Relevent portion of thread code
****************************************
public final void run() {
URL[] codeLLocation = new URL[1];
codeLLocation[0] = codeLocation;
NewURLClassLoader loader = new NewURLClassLoader(codeLLocation);
Thread.currentThread().setContextClassLoader(loader);
Object o = null;
while (keepRunning) {
if (o == null) {
try {
System.out.println("The parent classloader = " + loader.getParent());
Class c = loader.loadClass("<full_package_name_of_object");
System.out.println("Classloader = " + c.getClassLoader());
Object o = c.newInstance(); <===== Exception here.
****************************************
Extended URLClassLoader
****************************************
package org.fhtc.jde.threadtest;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class NewURLClassLoader extends URLClassLoader {
URL[] urls;
NewURLClassLoader(URL[] inputURLS) {
super(inputURLS);
urls = inputURLS;
}
public Class findClass(String name) throws ClassNotFoundException {
byte[] b = loadClassData(name);
if (b == null) {
throw (new ClassNotFoundException());
}
Class c = super.defineClass(name, b, 0, b.length);
return c;
}
public synchronized Class loadClass(String name)
throws ClassNotFoundException {
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
try {
c = this.findClass(name);
} catch (ClassNotFoundException e) {
c = super.loadClass(name);
}
}
return c;
}
private byte[] loadClassData(String className) {
byte[] buffer = new byte[1];
String realName = className.replace('.', '/');
realName += ".class";
try {
JarFile jarFile = new JarFile(urls[0].getFile());
JarEntry entry = jarFile.getJarEntry(realName);
if (entry != null) {
buffer = new byte[(int) entry.getSize()];
BufferedInputStream is = new BufferedInputStream(jarFile
.getInputStream(entry));
is.read(buffer);
} else {
buffer = null;
}
} catch (IOException e) {
buffer = null;
}
return buffer;
}
}