I've a custom class loader as follows
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class MyClassLoader extends ClassLoader
{
public String invoke(final String className, final String methodName, final String someString)
{
try {
final ClassLoader classLoader = getClass().getClassLoader();
final Class loadedClass = classLoader.loadClass(className);
final Constructor constructor = loadedClass.getConstructor();
final Object myClassObject = constructor.newInstance();
final Method method = loadedClass.getMethod(methodName, String.class);
final Object testStr = method.invoke(myClassObject, someString);
System.out.println(loadedClass.getClassLoader());
return (String) testStr;
}
catch (final ClassNotFoundException e) {
e.printStackTrace();
}
catch (final Exception e) {
e.printStackTrace();
}
return null;
}
}
and a class named Bus
public class Bus
{
public static String connection(final String incoming)
{
return "Bus " + incoming;
}
}
and a Tester class to test the code
public class Tester
{
public static void main(final String[] args) throws InterruptedException
{
for (int i = 0; i < 3; i++) {
final MyClassLoader mcl = new MyClassLoader();
final String s = mcl.invoke("Bus", "connection", "awesome");
System.out.println("Tester: " + s);
Thread.sleep(300);
}
}
}
Question: Why does the sysout inside MyClassLoader always print the same object (a.k.a class loader)? What am I doing wrong?
What I want to achieve is for each iteration in the Tester class, I would like the Bus class to be loaded into a new class loader
You need to implement your own class loader rather than just use the System class loader. Here is a rather trivial way that only works if the class file is in the expected directory.
public class MyClassLoader extends ClassLoader
{
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
try {
byte b[] = Files.readAllBytes(Paths.get("target/classes/"+name+".class"));
ByteBuffer bb = ByteBuffer.wrap(b);
return super.defineClass(name, bb,null);
} catch (IOException ex) {
return super.loadClass(name);
}
}
public String invoke(final String className, final String methodName, final String someString)
{
try {
final ClassLoader classLoader = this;
...