Vous êtes sur la page 1sur 15

¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

risingofsilversurfer.blogspot.com

¯\_(ツ)_/¯: Class Loading in Java


14-18 minutes

The other day one of my colleagues asked me whether I could

explain to him about Java class loading. Then I thought "I know
basics about Java Class Loading, but is it complete and accurate?".
So I decided to do some search about the topic and it ended with
writing this post.

When you launch a Java application using "java" command, one of


major operation that happens behind it is the loading of required

classes. There are 3 types of classes normally needed for running a


Java application.

1. Classes that defines the implementation of Java platform. These

classes are necessary for running basic Java Runtime Environment


(JRE).

2. Classes that implements the functionalities for Java Extension

mechanism.

3. Classes that implements the functionality of your application and


the 3rd party libraries required for running your application code.

1 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

Process of finding the byte code for a given class name and then

converting that byte code to a JVM internal representation of a


class, is known as class loading. JVM has 3 separate class loaders

for loading each of above mentioned sets of classes. In addition to


those, developers can create their own class loaders.

1. Bootstrap class loader

2. Extension class loader

3. System classpath class loader

More details about these class loaders are explained in below


sections. Few important things to remember is,

Each of those class loaders has different set of classpaths


(directories and jar files to find the classes) to check when it tries to

find/load a class. (e.g.: Bootstrap class loader loads class located in


"sun.boot.class.path" system property which normally point to a set

of jar files in jre/lib folder.)

JVM does not load all classes at the start-up, it only loads the

2 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

required set of classes, and then load the classes dynamically as

needed.

The same class loaded by two separate class loaders are not

equal. Therefore you cannot cast one of those class to other class,
although those were loaded from same class byte code. A loaded
class is internally identified by [the package name, class name, the

name of the class loader which it loaded]. (Two different class


loaders mentioned here does not have parent-child relationship. if
that is the case, the class is loaded by same parent.)

The classes loaded by Class Loaders are stored in method area in

PermGen area of JVM. Method Area stores the per-class


information such as

Class Loader Reference

Runtime Constant Pool

Field Data

Method Data

Method Code (Byte code + other information)

All threads share the same Method Area.

Java has following class loader types in addition to user built class

loaders.

Class Loader Types

3 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

Bootstrap Class Loader (aka Primordial or Null Class Loader)

Bootstrap Class Loader is the parent class loader of all other


class loaders. It is responsible for loading the key classes (from

java.* packages etc.) at the beginning of the class loading. It loads


the pre-requisite classes needed for supporting a basic Java
Runtime Environment. It has access to a set of trusted classes

which can be run by JVM without "verification". Bootstrap Class


Loader is implemented using native code (mostly in C), not using
Java code. But all other Class Loaders are implemented using Java

code.
So when you execute a java program with -verbose:class JVM

argument, You can see that first few lines in the output that starts
with "[Loaded" are related to the class loading done by Bootstrap

Class Loader from jre\lib\rt.jar file and other important jar files the
jre\lib directory in your Java installation. This location is known as

bootstrap classpath and you can read it from sun.boot.class.path


system property.

You can use -Xbootclasspath non-standard command line option

to change the directories of bootstrap class path, but it is not


recommended and it violates JRE binary code license. There are

two more variation of this command line option; -Xbootclasspath/a


to append to existing bootclasspath, and -Xbootclasspath/p to

prepend to existing bootclasspath.

4 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

Extension Class Loader

Extension Class Loader is immediate child of the Bootstrap Class


Loader. Extension Class Loader is responsible for loading classes

from Java extensions directories (value of java.ext.dirs system


property including "jre\lib\ext"). These locations has the jar files
which implements the Java extension APIs.

Extension Class Loader in JVM is implemented by


sun.misc.Launcher$ExtClassLoader. When Extension Class Loader
get a call to load a class, it first tries to delegate the loading to the

Bootstrap class loader (because it is the parent class loader). If


Bootstrap class loader cannot load the class, then Extension Class

Loader tries to load the class from "jre\lib\ext" directory or other


directories listed in "java.ext.dirs" system property.

System Class Loader (System Classpath Class Loader)

System Class Loader is the immediate child of the Extension Class

Loader. This class loader loads the classes from classes and jar

files in CLASSPATH environment variable or given in -classpath


command line option.

Some important points about Classpath of the System Class


Loader,

Default classpath is "." aka current directory.

You can use CLASSPATH environment variable to define the

5 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

classpath.

You can use -cp or -classpath command line option to define the
classpath, this will override the value defined in CLASSPATH

environment variable.

When you use -jar command line option, it will ignore the values in
-cp and -classpath command line options, and also the value of
CLASSPATH environment variable. It will only consider the Class-

Path attribute defined in the META-INF/mainfest.mf file of the jar


file.

If two classes with the same name exists in the classpaths, the

class loader will load the first found class.

Current value of the classpath being used by a java program can be

retrieved from java.class.path system property.

System Class Loader is implemented by

sun.misc.Launcher$AppClassLoader class and it is a child of

Extension Class Loader. You can change the System Classpath


Class Loader to use your own class loader implementation instead

of sun.misc.Launcher$AppClassLoader, by using
-Djava.system.class.loader command line option.

User Defined Class Loaders

Developers can create their own class loaders to support specific

6 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

requirements of their application. Possible examples for

implementing user defined class loaders,

to load classes through network.

to load classes which are auto generated at runtime.

to load classes from encrypted files.

to separate class loading of different applications which runs in


same JVM.

etc.

7 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

Class Loading Algorithm

Class loaders (at least JVM class loaders) follow following algorithm
when it wants to load a class. (This algorithm is based on

delegating the task to parent first.)

1. Check whether class is already available in the local cache of the


current class loader.

2. If the class was not found in the cache, ask (delegate) the parent
class loader to load the class. (Please remember that Bootstrap

Class Loader does not have a parent.)

3. Parent class loader also does above steps recursively until the
class found in its cache or no parent class loader found. (Ask

parent's parent class loader to load, if parent class loader did not
find the class in its cache.).

4. If the parent class loader can find and load the class, it store it in its

cache and return it to its child class loader.

5. If parent class loader cannot load the class, the class loader tries to

load the class from its classpaths (aka code sources).

6. If the class loader cannot find the class in its local cache and cannot

get the class from parent class loaders and cannot load the class

from its local code sources, it throws ClassNotFoundException.

8 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

Example: When system classpath class loader wants to load

javax.imageio.ImageIO class (a class belong to Java Extensions),

1. System Classpath Class Loader check whether it has

javax.imageio.ImageIO class loaded in its local cache.

2. It does not find it in local cache, so it ask its parent class loader
(which is Extensions Class Loader) to load the
javax.imageio.ImageIO class.

3. Extension Class Loader checks its local cache whether it has


javax.imageio.ImageIO class.

4. If it found the javax.imageio.ImageIO class in its local cache, it

returns it to the System Classpath Class Loader.

5. If it did not find the javax.imageio.ImageIO class in its local cache, it


ask its parent class loader (which is Bootstrap Class Loader) to load
the javax.imageio.ImageIO class.

6. Bootstrap Class Loader checks whether it has

javax.imageio.ImageIO in its local cache. If it has the class in local


cache, it returns it to Extension Class Loader method call. (But in

our example, Bootstrap class loader should not find the class in its

local cache, because the class is in extension classpath).

7. If Bootstrap Class Loader did not find it in its local cache, and
because it does not have any parent class loader, it tries to load the

javax.imageio.ImageIO class from its classpath aka its local code

9 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

sources (bootstrap classpath).

8. Because the class is belong to Java Extensions, Bootstrap Class


Loader does not find it in bootstrap classpath. Then it return the

method call to its child class loader (Extension Class Loader)


without any class loaded.

9. Then Extension Class Loader tries to find the


javax.imageio.ImageIO class in its classpath aka its local code

sources.

10. Because the class belongs to Java Extensions, Extension Class


Loader finds the class in its classpath and loads it. Then put the

class in its local cache. Then it returns the class to its child class
loader which is System Classpath Class Loader.

So when a class loader wants to load a class, it first check

whether class is already loaded in its local cache, then delegates


the loading to the parent class loader if it is not in the current class

loader's cache. The class loader will try to load the class itself, only

if the parent class loader cannot load the class.


Therefore the classes loaded by parent class loaders are visible

to the children class loaders of that parent class loader. But the
classes loaded by a child class loader are not visible to any of

parent class loader of the child. Due to this algorithm, a class

loaded by parent class loader will not be reloaded by a child class


loader of it.

10 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

Stages in Class Loading

There are 3 main stages in loading a class from byte code to proper

JVM internal representation.

1. Loading - Class Loader search for the class file (byte code) in the

classpath and the byte code is loaded to memory (as a ClassFile

structure). This step creates a basic structure for the class, but it
does not have all the important data filled yet.

2. Linking - This step tries to convert byte code data to proper runtime
information. This step is sub divided into 3 more sub steps.

1. Byte Code Verification - the byte code is checked for the correct
format and other checks. This step ensures that loaded class is

structurally correct.

11 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

2. Class Preparation - This step prepare the data structures to

represent methods, fields, and implemented interfaces etc. from the


byte code. This step create static fields and initialize those to their

default values.

3. Resolving - This step do the resolving of other classes referenced


by this class. (e.g.: Super classes, field types, method param types,

method local variable types)

3. Initializing - This step executes the static initializer blocks.

Class Data Sharing (CDS) feature

Class Data Sharing (CDS) is a feature introduced in JavaSE 5.0 (in


Oracle/Sun hotspot JVM) in order to reduce the java application

start-up time by improving class loading time. When the JRE is

installed in your machine, JRE loads the classes from system jar
files into internal representations and then dump those loaded

internal representations to a file known as "shared archive" (which


is located in jre/lib/[arch]/client/classes.jsa in UNIX

and in jre/bin/client/classes.jsa in Windows). During

subsequent JVM invocations, the "shared archive" is used by those

JVM processes by memory mapping to it, so reducing the loading


time of classes loaded by Bootstrap class loader (which also means

this memory mapped file is shared among multiple JVM processes).

If this feature is enabled, you will see many lines with "[Loaded

12 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

className from shared objects file]" when you run a java

application with "-verbose:class" command line argument. The list


of classes in the "shared archive" can be found in "jre/lib/classlist"

file.

You can use "-XShare" command line option to either enable or

disable class data sharing for your java application.

In JDK 8U40, Oracle has introduced an experimental feature


named Application Class Data Sharing (AppCDS) by extending

CDS, to allow developers to place classes from Standard


Extensions directories and from Application classpath in the "shared
archive".

Common Errors/Exceptions related to class loading

ClassNotFoundException

java.lang.ClassNotFoundException is thrown when your program

dynamically tries to load the class at runtime and the class loader
did not find the requested class. Main reason is, the class is not

available in the CLASSPATH.

This is normally thrown by methods like Class.forName(),


ClassLoader.loadClass(), ClassLoader.findSystemClass() when the

java program tries to load a class dynamically, using its string name.
Due to this reason, the compiler does not detect the unavailability of

the class at the compile time.

13 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

NoClassDefFoundError

java.lang.NoClassDefFoundError happens when JVM or a class


loader instance trying to load a class definition, but this class

definition cannot be found or loaded due to some reason.


Most of the time, the class was available in the classpath during the
compile time, but it is no longer available during the runtime.

Another possible reason is, the class is still available in the


classpath, but the class has static initialization blocks which fails
during the loading of the class.

References:

http://docs.oracle.com/javase/7/docs/technotes/guides/security
/spec/security-spec.doc5.html

http://docs.oracle.com/javase/7/docs/technotes/tools/
findingclasses.html

http://docs.oracle.com/javase/tutorial/ext/basics/install.html

http://javapapers.com/core-java/java-jvm-run-time-data-areas/

http://www.artima.com/insidejvm/ed2/jvm2.html

http://what-when-how.com/enterprise-javabeans-3/exploring-class-

loading-ejb-3/

http://blog.jamesdbloom.com/JVMInternals.html#method_area

https://docs.oracle.com/javase/tutorial/essential/environment

14 of 15 30/10/2018, 11:11 PM
¯\_(ツ)_/¯: Class Loading in Java about:reader?url=https://risingofsilversurfer.blogspot.com/2016/10/class-...

/paths.html

http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows
/classpath.html

http://docs.oracle.com/javase/7/docs/technotes/guides/extensions

/index.html

http://docs.oracle.com/javase/tutorial/ext/

https://blogs.oracle.com/sundararajan/entry
/understanding_java_class_loading

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

http://www.techjava.de/topics/2008/01/java-class-loading/

http://docs.oracle.com/cd/E11035_01/wls100/programming

/classloading.html

15 of 15 30/10/2018, 11:11 PM