How do I change the default class loader in Java?

Suppose I have three classes, classA, example ClassB and example ClassLoader. ClassA prints out HelloWorld and ClassB imports example ClassA and call its main () method If I do this:

It works and uses my classloader But if I do this:

ClassB uses my classloader, but classA (imported by ClassB) uses the default classloader

Is there any way to force java to always use my classloader (unless another classloader is explicitly specified)?

Editor: thanks for the following ŭ According to loebermann's answer, I found that the problem is that I call the parent class loader to load the classes I don't need to touch, and those loaded classes are set as the context class loader, so the imported classes use the parent class loader of my custom loader (confusing, sorry) now I can read each class manually to make it work, but it looks a lot, because I copied the code of urlclassloader directly Is there any way to tell the parent class loader to find and define classes, but set the context class loader of class as your custom class loader?

Solution

If your class loader is implemented correctly, it will first ask its parent class loader for any classes that should be loaded

The parent class loader of your loader may be the usual application class loader This means that each class loaded by your class loader will be searched on the application class loader first and only if you can't find it

All classes defined by your classloader will also search for the required classes on the classloader If they do not, your classA is not loaded by your loader

If this doesn't help, you need to display some code about how to get the results

Ideas about what to do:

class ModifyingClassLoader extends urlclassloader {

    // TODO: add constructors

    private boolean needsModifying(String name) {
        // TODO
    }

    private byte[] modifyClass(InputStream original) throws IOException {
        // TODO
    }

    public Class<?> findClass(String name) throws {
        if(needsModifying(name)) {
            try {
                InputStream classData = getResourceAsStream(name.replace('.','/') + ".class");
                if(classData == null) {
                    throw new ClassNotFoundException("class " + name + " is not findable");
                }
                byte[] array = modifyClass(classData);
                return defineClass(name,array,array.length);
            }
            catch(IOException io) {
                throw new ClassNotFoundException(io);
            }
        }
        else {
            return super.findClass(name);
        }
    }
}

To your question:

No, the classloader of a class is always a class called to create the defineclass method of the class (context class loader is something else - it is thread specific and can only be used by classes that explicitly want to use it, rather than by resolving their own direct dependencies.)

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>