Custom Java classloader not being used to load dependencies?

后端 未结 5 1184
逝去的感伤
逝去的感伤 2021-02-05 10:28

I\'ve been trying to set up a custom classloader that intercepts classes to print out which classes are being loaded into the application. The classloader looks like this

<
5条回答
  •  感情败类
    2021-02-05 11:06

    If you want to print the classes as they are loaded, how about switching on the verbose:class option on the JVM?

    java -verbose:class your.class.name.here
    

    To answer your direct questions:

    Why is that? I was under the impression that the classloader used to load a class C would be used to load all the other classes needed by C, but that's clearly not happening here. Is that assumption mistaken? If it is, how do i set it up such that all the transitive dependencies of C are loaded by my classloader?

    While searching the ClassLoaders, the search is performed from the leaf ClassLoader to the root, when Java works out a new class has to be loaded, it is performed from the root of the ClassLoader tree back down to the leaf that initiated the class resolution.

    Why? Consider if your custom class wanted to load something from the Java standard libraries. The correct answer is that this should be loaded by the System ClassLoader so that class can be maximally shared. Especially when you consider that the class being loaded would then potentially load a whole lot more classes.

    This also solves the problem that potentially you could end up with multiple system Classes instances being loaded in different ClassLoaders - each with the same fully qualified name. EDIT Classes would be resolved correctly in their ClassLoader. However there are two problems.

    1. Let's say we have two String instances, a and b. a.getClass().isInstance(b) and a.getClass() == b.getClass() are not be true if a and b were instantiated in different ClassLoaders. This would cause horrific problems.
    2. Singletons: they would not be singletons - you can have one per ClassLoader.

    END EDIT

    One other observation: Just like you have set up a ClassLoader to specifically load classes from, interpreters often themselves create ClassLoader instances into which they load the interpreting environment and the script. That way, if the script changes, the ClassLoader can be dropped (and with it the script), and reloaded in a new ClassLoader. EJBs and Servlets also use this trick.

提交回复
热议问题