Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are all dependencies of a class loaded by the same classloader?

  • In my /tomcat/lib dir I have class SharedClass (which is thus shared with all web apps).
  • In my web app's WEB-INF/lib I have class LocalClass.
  • SharedClass has a reference to LocalClass.

In my web app I try to create an instance of SharedClass but it fails with the message:

NoClassDefFoundError: LocalClass.

Since SharedClass is shared and LocalClass is local to my web app I was hoping it would work, but it doesn't.

My suspicion is that SharedClass is loaded by the Tomcat parent classloader and LocalClass is loaded by the Web App classloader. Since SharedClass was loaded by the parent, I assume that all of its dependencies must also be loaded by the parent. Thus, the parent can't find LocalClass and it throws the Error.

Does this make sense? Is there any way around this (without writing my own classloader)?

like image 991
dough Avatar asked Jan 11 '13 22:01

dough


People also ask

Can we load the same class by two ClassLoader?

A class is always identified using its fully qualified name (package. classname). So when a class is loaded into JVM, you have an entry as (package, classname, classloader). Therefore the same class can be loaded twice by two different ClassLoader instances.

How do I know what ClassLoader loads a class?

To know the ClassLoader that loads a class the getClassLoader() method is used. All classes are loaded based on their names and if any of these classes are not found then it returns a NoClassDefFoundError or ClassNotFoundException.

How are classes loaded by JVM?

In order to actually load a class, the JVM uses Classloader objects. Every already loaded class contains a reference to its class loader, and that class loader is used to load all the classes referenced from that class.

Which ClassLoader loads the files from JDK directory?

The Bootstrap class loader loads the basic runtime classes provided by the JVM, plus any classes from JAR files present in the system extensions directory. It is parent to the System class loader. To add JAR files to the system extensions, directory, see Using the Java Optional Package Mechanism.


1 Answers

ClassLoaders are hierarchical. A class loader has a parent, and sees the classes of its parent. The reverse is not true. So a class loaded by the webapp's classloader has access to the classes loaded by the common Tomcat classloader (its parent), which has access to the JRE classes (the parent of Tomcat's classloader).

See the Tomcat documentation and the ClassLoader javadoc for more details.

like image 108
JB Nizet Avatar answered Sep 28 '22 08:09

JB Nizet