Java example with ClassLoader

22,879

Solution 1

Class<?> classS = urlcl.loadClass("michal.collection.Stack");
[...]
Object object = classS.newInstance();
michal.collection.Stack new_name = (michal.collection.Stack) object;

So you're attempting to dynamically load a class and then you statically refer to it. If you can already statically link to it, then its loaded and you can't load it again. You'll need to access the methods by reflection.

What you would usually do is have the loaded class implement an interface from the parent class loader. After an instance is created (usually just a single instance), then you can refer to it through a reference with a type of the interface.

public interface Stack {
   [...]
}
[...]
    URLClassLoader urlcl = URLClassLoader.newInstance(new URL[] {
       new URL(
           "file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar"
       )
    });
    Class<?> clazz = urlcl.loadClass("michal.collection.StackImpl");
    Class<? extends Stack> stackClass = clazz.asSubclass(Stack.class);
    Constructor<? extends Stack> ctor = stackClass.getConstructor();
    Stack stack = ctor.newInstance();

(Usual Stack Overflow disclaimer about not so much as compiling.)

You'll need to add error handling to taste. URLClassLoader.newInstance adds a bit of refinement to URLClassLoader. Class.newInstance has completely broken exception handling and should be avoided.

Solution 2

The above answers are both wrong, they don't understand the root problem. Your main refers to the Stack class which was loaded by one class loader. Your urlclassloader is attempting to load a class with the same name. You cannot cast the loaded to the referred because they are not the same, they belong to different classloaders. You can print the has code of each to see they are different. An equality test will also show the cclass references to be different. Your problem is probably because dependent classes referenced by sstack can be found, which will result in NoClassDefErrors etc. Your main will probably fail with a classcastexception.

Share:
22,879
Michał
Author by

Michał

Updated on February 03, 2022

Comments

  • Michał
    Michał over 2 years

    I have small problem. I learn java SE and find class ClassLoader. I try to use it in below code: I am trying to use URLClassLoader to dynamically load a class at runtime.

    URLClassLoader urlcl = new URLClassLoader(new URL[] {new URL("file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar")});
    Class<?> classS = urlcl.loadClass("michal.collection.Stack");
    for(Method field: classS.getMethods()) {
         System.out.println(field.getName());
    }
    Object object = classS.newInstance();
    michal.collection.Stack new_name = (michal.collection.Stack) object;
    

    The java virtual machine does not see me class, and I get the following exception:

    Exception in thread "main" java.lang.Error: Unresolved compilation problems: michal cannot be resolved to a type michal cannot be resolved to a type at Main.main(Main.java:62)
    

    Do you know how I can solve this problem?