Java class loader: Difference between revisions

Content deleted Content added
m JAR hell: punctuation
 
(260 intermediate revisions by more than 100 users not shown)
Line 1:
The '''Java Classloaderclass loader''' is a, part of the [[Java Runtime Environment]] that dynamically, [[LoaderDynamic (computing)loading|loaddynamically loads]]s [[Java class]]es into the [[Java virtual machine|Java Virtual Machine]].<ref>{{cite Usually classes are only loaded [[on demand]]. The Java run time system does not need to know about files and file systems because of class loaders. [[Delegation (programming)|Delegation]] is an important concept to understand when learning about class loaders.web
|last1=Mcmanis |first1=Chuck
|date=1996-10-01 |df=mdy
|url=https://www.infoworld.com/article/2077260/learn-java-the-basics-of-java-class-loaders.html
|title=The basics of Java class loaders
|work=[[JavaWorld]]
|accessdate=2020-07-13
}}</ref> Usually classes are only loaded [[lazy initialization|on demand]]. The virtual machine will only load the class files required for executing the program.{{sfn | Horstmann | 2022 | loc=§10.1.1 The Class-Loading Process}} The Java run time system does not need to know about files and file systems as this is [[Delegation _(object-oriented_programming)|delegated]] to the class loader.
 
A [[Library (computing)|software library]] is a collection of more or less related [[object code]].
In the [[Java (programming language)|Java language]], libraries are typically packaged in [[jar-JAR (file format)|JarJAR files]]. Libraries can contain variousobjects of different sortstypes. of objects, theThe most important type of object contained in a Jar file is a [[Java class]]. A class can be thought of as a named unit of code. The class loader is responsible for locating libraries, reading their contents, and loading the classes contained within the libraries. This loading is typically done "on demand", in that it does not occur until the class is actually usedcalled by the program. A class with a given name can only be loaded [[Once and only once|once]] by a given classloaderclass loader.
 
Each Java class must be loaded by a class loader.{{sfn | Horstmann | 2022 | loc=§8.2.5 Writing Byte Codes to Memory}}<ref name="Christudas">{{cite web
The classloading process is fairly complicated, and is the subject of much confusion in [[software deployment]] and [[Software development|development]]. Java programs may make use of external or [[third party library|third party libraries]] (that is, libraries written and provided by someone other than the author of the program) or may itself be composed, at least in part, by a number of libraries.
|last1=Christudas |first1=Binildas
|date=2005-01-26 |df=mdy
|url=http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.html
|title=Internals of Java Class Loading
|archiveurl=https://web.archive.org/web/20180510223447/http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.html
|archivedate=2018-05-10
|work=onjava.com
}}</ref> Furthermore, [[Java (software platform)|Java]] programs may make use of [[Library (computing)|external libraries]] (that is, libraries written and provided by someone other than the author of the program) or they may be composed, at least in part, of a number of libraries.
 
When the JVM is started, three class loaders are used:<ref name="TJT:UECL">{{cite web
Each Java class must be loaded by a class loader.
|url=https://docs.oracle.com/javase/tutorial/ext/basics/load.html
When the JVM is started, three class loaders are used:-
|title=Understanding Extension Class Loading
# Bootstrap class loader
|department=The Java Tutorials
|work=docs.oracle.com
|accessdate=2020-07-13
}}</ref><ref>{{cite web
|last1=Sosnoski |first1=Dennis
|date=2003-04-29 |df=mdy
|url=http://www.ibm.com/developerworks/java/library/j-dyn0429/
|title=Classes and class loading
|work=IBM DeveloperWorks
|accessdate=2008-01-26
}}</ref>{{sfn | Horstmann | 2022 | loc=§10.1.1 The Class-Loading Process}}
# Bootstrap class loader
# Extensions class loader
# System class loader
 
The bootstrap class loader loads the core Java libraries<ref group=fn>These libraries are stored in [[JAR (file format)|Jar files]] called ''rt.jar'', ''core.jar'', ''server.jar'', etc.</ref> located in the <code><JAVA_HOME>/jre/lib</code> (or <code><JAVA_HOME>/jmods></code> for Java 9 and above) directory. This class loader, which is part of the core JVM, is written in native code. The bootstrap class loader is not associated with any {{java|ClassLoader}} object.{{sfn | Horstmann | 2022 | loc=§10.1.1 The Class-Loading Process}} For instance, {{java|StringBuilder.class.getClassLoader()}} returns {{java|null}}.{{sfn | Horstmann | 2022 | loc=§10.1.1 The Class-Loading Process}}
The bootstrap class loader loads the core Java libraries, i.e. core.jar, server.jar etc. in the <JAVA_HOME>/lib directory. This class
loader, which is part of the core JVM, is written in native code.
 
The extensions class loader loads the code in the extensions directories (<code><JAVA_HOME>/jre/lib/ext</code>,<ref name="TJT:UECL"/> or any other directory specified
by the <code>java.ext.dirs</code> system property). It is implemented by
the sun.misc.Launcher$ExtClassLoader class.
 
The system class loader loadingloads code found on <code>java.class.path</code>, which maps to the system <code>[[Classpath (Java)|CLASSPATH]]</code> [[environment variable. This is implemented by the sun.misc.Launcher$AppClassLoader class]].
 
==User-defined class loaders==
== JAR hell ==
The Java class loader is written in Java. It is therefore possible to create a custom class loader without understanding the finer details of the Java Virtual Machine. Apart from the Bootstrap class loader, every Java class loader has a parent class loader.{{sfn | Horstmann | 2022 | loc=10.1.2 The Class Loader Hierarchy}} The parent class loader is defined when a new class loader is instantiated or set to the virtual machine's system default class loader.
 
This makes it possible (for example):
'''Jar hell''' is a term similar to [[DLL hell]] used to describe all the various ways in which the classloading process can end up not working.
* to load or unload classes at runtime (for example to load libraries dynamically at runtime, even from an [[Hypertext Transfer Protocol|HTTP]] resource). This is an important feature for:
** implementing scripting languages, such as [[Jython]]
** using [[JavaBean|bean]] builders
** allowing user-defined [[extensibility]]
** allowing multiple [[namespace]]s to communicate. This is one of the foundations of [[Common Object Request Broker Architecture|CORBA]] / [[Java remote method invocation|RMI]] protocols for example.
* to change the way the [[Java bytecode|bytecode]] is loaded (for example, it is possible to use [[Encryption|encrypted]] Java class bytecode<ref>{{cite web
|last1=Roubtsov |first1=Vladimir
|date=2003-05-09 |df=mdy
|url=https://www.infoworld.com/article/2077342/cracking-java-byte-code-encryption.html
|title=Cracking Java byte-code encryption
|work=[[JavaWorld]]
|accessdate=2020-07-13
}}</ref>).
* to modify the loaded bytecode (for example, for load-time [[aspect weaver|weaving]] of aspects when using [[aspect-oriented programming]]).
 
== Class loaders in Jakarta EE ==
* One case is when a developer or deployer of a [[Java application]] has accidentally made two different versions of a library available to the system. This is not considered an [[error]] by the system. Rather, the system will load classes from one or the other library. So, a developer who thinks he has replaced a library with a new version, but who has instead simply added the new library to the list of available libraries, may be surprised to see the application still behaving as though the old library is in use, which of course, it may well be.
[[Jakarta EE]] (formerly Java EE and J2EE) application servers typically load classes from a deployed [[WAR (file format)|WAR]] or [[EAR (file format)|EAR]] archive by a tree of class loaders, isolating the application from other applications, but sharing classes between deployed modules. So-called "[[servlet container]]s" are typically implemented in terms of multiple class loaders.<ref name="Christudas"/><ref>{{cite web
|last1=deBoer |first1=Tim
|last2=Karasiuk |first2=Gary
|date=2002-08-21 |df=mdy
|url=https://www.ibm.com/developerworks/websphere/library/techarticles/0112_deboer/deboer.html
|title=J2EE Class Loading Demystified
|work=IBM DeveloperWorks
|accessdate=2008-01-26
}}</ref>
 
== {{anchor|jarhell}} JAR hell ==
* Another version of the problem arises when two libraries (or a library and the application) require different versions of the same third library. Without taking extraordinary measures (which may or may not even be available, depending on the circumstances) there is no way to load both versions of the third library.
JAR hell is a term similar to [[DLL hell]] used to describe all the various ways in which the classloading process can end up not working.<ref>{{Cite web|url=http://incubator.apache.org/depot/version/jar-hell.html|archive-url = https://web.archive.org/web/20130601002059/http://incubator.apache.org/depot/version/jar-hell.html|archive-date = 2013-06-01|title = Depot - Apache Incubator}}</ref> Three ways JAR hell can occur are:
* Accidental presence of two different versions of a library installed on a system. This will not be considered an error by the system. Rather, the system will load classes from one or the other library. Adding the new library to the list of available libraries instead of replacing it may result in the application still behaving as though the old library is in use, which it may well be.
* Multiple libraries or applications require different versions of library '''foo'''. If versions of library '''foo''' use the same class names, there is no way to load the versions of library '''foo''' with the same class loader.
* The most complex JAR hell problems arise in circumstances that take advantage of the full complexity of the classloading system. A Java program is not required to use only a single "flat" class loader, but instead may be composed of several (potentially very many) nested, cooperating class loaders. Classes loaded by different class loaders may interact in complex ways not fully comprehended by a developer, leading to errors or bugs that are difficult to analyze, explain, and resolve.<ref>{{Cite web|url=http://articles.qos.ch/classloader.html|title=Taxonomy of class loader problems with Jakarta Commons Logging}}</ref>
 
The [[OSGi]] Alliance specified (starting as JSR 8 in 1998) a modularity framework that aims to solve JAR hell for current and future VMs in ME, SE, and EE that is widely adopted. Using metadata in the JAR [[manifest file|manifest]], JAR files (called bundles) are wired on a per-package basis. Bundles can export packages, import packages and keep packages private, providing the basic constructs of modularity and versioned dependency management.
* The most complex ''Jar hell'' problems arise in circumstances that take advantage of the full complexity of the classloading system. A Java program is not required to use only a single "flat" classloader, but instead may be composed of several (an indefinite number, in fact) nested, cooperating classloaders. This is not as uncommon as one might think: so-called "[[servlet]] containers" are typically implemented in terms of multiple classloaders. The interactions between classloaders is too complex to be fully described here. It is sufficient to say that classes loaded by different classloaders [[Emergent properties|interact in ways which may not be fully comprehended by the developer]], leading to inexplicable errors or bugs.
 
[[Java version history#Java SE 9|Java 9]] introduced the [[Java Platform Module System]] in 2017. This specifies a distribution format for collections of Java code and associated resources. It also specifies a repository for storing these collections, or ''[[Modular programming|modules]]'', and identifies how they can be discovered, loaded and checked for integrity. It includes features such as namespaces with the aim of fixing some of the shortcomings in the existing [[JAR (file format)|JAR]] format. The Java Platform Module System follows a different philosophy from the OSGi architecture that aims at providing modularity for the Java Runtime Environment in a backwards-compatible way that uses the default mechanism of loading classes that the JRE provides. However, since the Java Platform Module System does not offer the ability for controlled co-existence of libraries with different versions, it does not fully address the JAR hell problem.<ref>{{cite web|first1=Neil|last1=Bartlett|first2=Kai|last2=Hackbarth|title=Java 9, OSGi and the Future of Modularity (Part 1)
== See also ==
|url=https://www.infoq.com/articles/java9-osgi-future-modularity/#1|publisher=InfoQ|date=2016-09-22}}</ref>
 
==See also==
* [[Loader (computing)]]
* [[Dynamic loading]]
* [[DLL hell]]
* [[OSGi]]
*[[Apache Maven]], automated software build tool with dependency management
* [[Classpath (Java)]]
* [[Java Platform Module System]]
 
==Footnotes==
{{reflist|group=fn}}
 
==References==
{{reflist}}
 
== External links ==
*Article Chuck McManis, "[httphttps://www.javaworldinfoworld.com/javaworldarticle/jw2077260/learn-10java-1996/jwthe-10basics-indepthof-java-class-loaders.html The basics of Java class loaders]", by [[Chuck Mcmanis]]1996
*Article Brandon E. Taylor, "[http://www.developer.com/java/other/article.php/2248831 Java Class Loading: The Basics]" by{{Webarchive|url=https://web.archive.org/web/20201109091535/http://www.developer.com/java/other/article.php/2248831 [[Brandon|date=2020-11-09 E.}}", Taylor]]2003
* {{cite book | last=Horstmann | first=Cay | title=Core Java | publisher=Oracle Press Java | date=April 15, 2022 | isbn=0-13-787107-4}}
*Article "[http://www.devx.com/Java/Article/31614 Take Control of Class Loading in Java]" by [[Jeff Hanson]]
* Jeff Hanson, "[http://www.devx.com/Java/Article/31614 Take Control of Class Loading in Java] {{Webarchive|url=https://web.archive.org/web/20201204030013/http://www.devx.com/Java/Article/31614 |date=2020-12-04 }}", 2006-06-01
*Article "[http://www-128.ibm.com/developerworks/java/library/j-dyn0429/ Java programming dynamics, Part 1: Classes and class loading]" by [[Dennis Sosnoski]]
* Andreas Schaefer, "[https://web.archive.org/web/20180506212821/http://www.onjava.com/pub/a/onjava/2003/11/12/classloader.html Inside Class Loaders]", 2003-11-12
*Article "[http://www-128.ibm.com/developerworks/websphere/library/techarticles/0112_deboer/deboer.html J2EE Class Loading Demystified]" by [[Tim deBoer]] and [[Gary Karasiuk]]
* Sheng Liang and Gilad Bracha, "[https://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.18.762 Dynamic class loading in the Java virtual machine]", In Proceedings of the 13th ACM Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA'98), ACM SIGPLAN Notices, vol. 33, no. 10, ACM Press, 1998, pp.&nbsp;36–44 {{doi|10.1145/286936.286945}}
*Article "[http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.html Internals of Java Class Loading]" by [[Binildas Christudas]]
* Jeremy Whitlock, "[https://web.archive.org/web/20080628071703/http://dev2dev.bea.com/blog/jcscoobyrs/archive/2005/05/realworld_use_f.html Real-World Use For Custom ClassLoaders]", May 2005
*Article "[http://www.onjava.com/pub/a/onjava/2003/11/12/classloader.html Inside Class Loaders]" by [[Andreas Schaefer]]
* Christoph G. Jung, "[https://web.archive.org/web/20130201093532/http://www.roseindia.net/javatutorials/hotdeploy.shtml Classloaders Revisited Hotdeploy]", ''Java Specialist Newsletter'', 2001-06-07
*Article "[http://citeseer.ist.psu.edu/liang98dynamic.html Dynamic class loading in the Java virtual machine]" by [[Sheng Liang]] and [[Gilad Bracha]]
* Don Schwarz, "[https://web.archive.org/web/20180506083919/http://www.onjava.com/pub/a/onjava/2005/04/13/dependencies.html Managing Component Dependencies Using ClassLoaders]", 2005-04-13
*[http://java.sun.com/javase/6/docs/api/java/lang/ClassLoader.html API description]
*[http://java.sun.com/docs/books/tutorial/ext/basics/load.html Understanding Extension Class Loading from Sun's Java Tutorial]
*[http://www.jayasoft.fr/index.php?option=com_content&task=view&id=29&Itemid=54 Dependency manager] - now at [http://incubator.apache.org/projects/ivy.html Apache incubator]
*[http://jcloader.sourceforge.net Dynamic loading of classes directly from JAR files]
 
[[Category:Java (programming language)]]
[[Category:Anti-patterns]]