Qu'est-ce qu'un ClassLoader Java?


174

En quelques phrases simples, qu'est-ce qu'un ClassLoader Java, quand est-il utilisé et pourquoi?

OK, j'ai lu un article wiki. ClassLoader charge les classes. D'ACCORD. Donc, si j'inclus des fichiers jar et que je les importe, un ClassLoader fait le travail.

Pourquoi devrais-je m'embêter avec ce ClassLoader? Je ne l'ai jamais utilisé et je ne savais pas qu'il existait.

La question est, pourquoi la classe ClassLoader existe-t-elle? Et aussi, comment l'utilisez-vous dans la pratique? (Des cas existent, je sais.)


Vous obtiendrez de meilleurs résultats si vous affinez votre question, par exemple en pointant une partie spécifique que vous ne comprenez pas, comment elle se rapporte à une autre langue que vous connaissez, etc.
JRL

75
C'est une question tout à fait raisonnable, vue du point de vue de quelqu'un qui cherche quelques phrases simples pour expliquer le concept
oxbow_lakes

Cette vidéo pourrait vous intéresser: obtenez-vous vraiment des chargeurs de classe?
asmaier

Réponses:


231

Tiré de ce joli tutoriel de Sun:

Motivation

Les applications écrites dans des langages de programmation compilés statiquement, tels que C et C ++, sont compilées dans des instructions natives spécifiques à la machine et enregistrées sous forme de fichier exécutable. Le processus de combinaison du code en un code natif exécutable est appelé liaison - la fusion d'un code compilé séparément avec un code de bibliothèque partagé pour créer une application exécutable. Ceci est différent dans les langages de programmation compilés dynamiquement tels que Java. En Java, les fichiers .class générés par le compilateur Java restent tels quels jusqu'à ce qu'ils soient chargés dans la machine virtuelle Java (JVM) - en d'autres termes, le processus de liaison est effectué par la JVM au moment de l'exécution. Les classes sont chargées dans la machine virtuelle Java selon les besoins. Et lorsqu'une classe chargée dépend d'une autre classe, cette classe est également chargée.

Lorsqu'une application Java est lancée, la première classe à exécuter (ou le point d'entrée dans l'application) est celle avec la méthode publique static void appelée main (). Cette classe a généralement des références à d'autres classes, et toutes les tentatives de chargement des classes référencées sont effectuées par le chargeur de classe.

Pour avoir une idée de ce chargement de classe récursif ainsi que de l'idée de chargement de classe en général, considérez la classe simple suivante:

public class HelloApp {
   public static void main(String argv[]) {
      System.out.println("Aloha! Hello and Bye");
   }
}

Si vous exécutez cette classe en spécifiant l'option de ligne de commande -verbose: class, afin qu'elle imprime les classes en cours de chargement, vous obtiendrez une sortie qui se présente comme suit. Notez qu'il ne s'agit que d'une sortie partielle car la liste est trop longue pour être affichée ici.

prmpt>java -verbose:class HelloApp



[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]

Comme vous pouvez le voir, les classes d'exécution Java requises par la classe d'application (HelloApp) sont chargées en premier.

Chargeurs de classes dans la plate-forme Java 2

Le langage de programmation Java ne cesse d'évoluer pour faciliter la vie des développeurs d'applications au quotidien. Cela se fait en fournissant des API qui vous simplifient la vie en vous permettant de vous concentrer sur la logique métier plutôt que sur les détails de mise en œuvre des mécanismes fondamentaux. Ceci est évident par le récent changement de J2SE 1.5 vers J2SE 5.0 afin de refléter la maturité de la plateforme Java.

À partir de JDK 1.2, un chargeur de classe d'amorçage intégré à la JVM est responsable du chargement des classes de l'environnement d'exécution Java. Ce chargeur de classe charge uniquement les classes qui se trouvent dans le chemin des classes de démarrage, et comme il s'agit de classes approuvées, le processus de validation n'est pas effectué comme pour les classes non approuvées. En plus du chargeur de classe d'amorçage, la machine virtuelle Java dispose d'un chargeur de classe d'extension responsable du chargement des classes à partir des API d'extension standard, et d'un chargeur de classe système qui charge les classes à partir d'un chemin de classe général ainsi que vos classes d'application.

Puisqu'il y a plus d'un chargeur de classe, ils sont représentés dans une arborescence dont la racine est le chargeur de classe bootstrap. Chaque chargeur de classe a une référence à son chargeur de classe parent. Lorsqu'un chargeur de classe est invité à charger une classe, il consulte son chargeur de classe parent avant de tenter de charger l'élément lui-même. Le parent consulte à son tour son parent, et ainsi de suite. Ce n'est donc qu'après que tous les chargeurs de classes ancêtres n'ont pas pu trouver la classe que le chargeur de classes actuel est impliqué. En d'autres termes, un modèle de délégation est utilisé.

La classe java.lang.ClassLoader

Le java.lang.ClassLoaderest une classe abstraite qui peut être sous-classée par les applications qui doivent étendre la manière dont la JVM charge dynamiquement les classes. Les constructeurs dans java.lang.ClassLoader(et ses sous-classes) vous permettent de spécifier un parent lorsque vous instanciez un nouveau chargeur de classe. Si vous ne spécifiez pas explicitement un parent, le chargeur de classe système de la machine virtuelle sera affecté en tant que parent par défaut. En d'autres termes, la classe ClassLoader utilise un modèle de délégation pour rechercher des classes et des ressources. Par conséquent, chaque instance de ClassLoader a un chargeur de classe parent associé, de sorte que lorsqu'il est demandé de trouver une classe ou des ressources, la tâche est déléguée à son chargeur de classe parent avant de tenter de trouver la classe ou la ressource elle-même. La loadClass()méthode du ClassLoader effectue les tâches suivantes, dans l'ordre, lorsqu'elle est appelée pour charger une classe:

Si une classe a déjà été chargée, elle la renvoie. Sinon, il délègue la recherche de la nouvelle classe au chargeur de classe parent. Si le chargeur de classe parent ne trouve pas la classe, loadClass()appelle la méthode findClass()pour rechercher et charger la classe. La finalClass()méthode recherche la classe dans le chargeur de classe actuel si la classe n'a pas été trouvée par le chargeur de classe parent.


Il y en a plus dans l'article original, qui vous montre également comment implémenter vos propres chargeurs de classe réseau, ce qui répond à votre question de savoir pourquoi (et comment). Voir également la documentation de l' API .


47

La plupart des développeurs Java n'auront jamais besoin d'utiliser explicitement des chargeurs de classe (sauf pour charger des ressources afin que cela fonctionne toujours lorsqu'ils sont regroupés dans des JAR), et encore moins d'écrire les leurs.

Les ClassLoaders sont utilisés dans les grands systèmes et les applications serveur pour faire des choses comme:

  • Modulariser un système et charger, décharger et mettre à jour les modules lors de l'exécution
  • Utiliser différentes versions d'une bibliothèque d'API (par exemple un analyseur XML) en parallèle
  • Isolez les différentes applications exécutées dans la même JVM (en vous assurant qu'elles n'interfèrent pas entre elles, par exemple via des variables statiques)

29

La question est "Pourquoi devrait-on déranger cette classe ClassLoader existe"?

Eh bien, surtout pour que vous puissiez réparer les choses en cas de problème :-).

C'est vrai, tant que vous écrivez simplement une application, que vous la compilez dans un JAR et que vous incluez peut-être quelques fichiers JAR de bibliothèque supplémentaires, vous n'avez pas besoin de connaître les chargeurs de classe, cela fonctionnera.

Néanmoins, il est utile d'en savoir un peu plus sur les chargeurs de classe et le chargement de classe pour mieux comprendre ce qui se passe dans les coulisses. Par exemple, les "initialiseurs statiques" s'exécuteront lorsqu'une classe est chargée, donc pour comprendre quand ils seront exécutés, vous devez savoir comment le chargeur de classe décide quand les charger.

aussi .. comment l'utilisez-vous dans la pratique?

Pour les cas simples, vous n'en avez pas besoin. Cependant, si vous avez besoin de charger du code dynamiquement à l'exécution avec un contrôle explicite d'où il vient (par exemple, chargement sur un réseau, chargement de plugins non disponibles au moment de la compilation, etc.), vous devrez peut-être en faire plus. Ensuite, vous pouvez par exemple écrire votre propre chargeur de classe. Voir les autres réponses pour les liens.


14

ClassLoaderen Java est une classe qui est utilisée pour charger des fichiers de classe en Java. Le code Java est compilé dans un fichier de classe parjavac compilateur et JVM exécute le programme Java, en exécutant des codes d'octets écrits dans un fichier de classe.

ClassLoader est responsable du chargement des fichiers de classe à partir du système de fichiers, du réseau ou de toute autre source. Il existe trois chargeurs de classe par défaut utilisés dans Java, Bootstrap , Extension et System ou Application class loader.

ClassLoader


Comment fonctionne ClassLoader

## Interaction de ClassLoader avec JVM entrez la description de l'image ici

En savoir plus @: how-classloader-works-in-java.html


6

Les chargeurs de classe sont un composant fonctionnel de JVM, qui charge les données de classe à partir du fichier '.class' ou depuis le réseau vers la zone de méthode du tas.

Cela semble faire partie intégrante de la JVM, mais en tant qu'utilisateur final de Java, pourquoi devrais-je être concerné? Voici pourquoi:

Chaque chargeur de classe a son propre espace de nom et les classes appelées par un chargeur de classe particulier pénètrent dans son espace de nom.

Les classes appelées par deux chargeurs de classes différents n'auront pas de visibilité l'une sur l'autre, ce qui se traduira par une sécurité améliorée.

Le mécanisme de délégation enfant parent du chargeur de classe garantit que les classes API Java ne pourront jamais être piratées par du code non autorisé.

Pour plus de détails, regardez ici


1

Les chargeurs de classes sont hiérarchiques. Les classes sont introduites dans la JVM car elles sont référencées par leur nom dans une classe qui s'exécute déjà dans la JVM.

Comment la toute première classe s'est chargée?
La toute première classe est chargée à l'aide destatic main() méthode déclarée dans votre classe. Toutes les classes chargées par la suite sont chargées par les classes, qui sont déjà chargées et en cours d'exécution.

Un chargeur de classe crée un espace de noms. Toutes les JVM incluent au moins un chargeur de classe intégré à la JVM, appelé chargeur de classe primordial (ou bootstrap) . C'est une chose, et nous examinerons les chargeurs de classes non primordiaux. La JVM a des hooks pour permettre aux chargeurs de classe définis par l'utilisateur d'être utilisés à la place du chargeur de classe primordial. Voici les chargeurs de classe créés par la JVM.

Bootstrap (primordial) Ce chargeur de classe n'est pas rechargeable. Charge les classes internes JDK, les packages java. * (Charge généralement rt.jar et i18n.jar). Extesions Ce chargeur de classe n'est pas rechargeable. Charge les fichiers jar à partir du répertoire des extensions JDK (généralement lib / ext de JRE). Système Ce chargeur de classe n'est pas rechargeable. Charge les classes à partir du chemin d'accès aux classes système.

http://www.sbalasani.com/2015/01/java-class-loaders.html


1

Lorsque vous demandez pourquoi la classe ClassLoader existe, la raison est assez simple: c'est la classe responsable de la recherche et du chargement des fichiers de classe au moment de l'exécution .

Élaborons-le.

Dans JVM, chaque classe est chargée par une instance de java.lang.ClassLoader. Chaque fois qu'une nouvelle JVM est démarrée par votre java <classname>commande de lancement de programme Java habituelle , la première étape consiste à charger toutes les classes clés en mémoire nécessaires pour un fonctionnement correct comme java.lang.Objectet d'autres classes d'exécution ( rt.jar).

Maintenant, il y a en fait 3 parties dans ClassLoader:

  • Le BootstrapClassLoaderest responsable de rendre ces classes disponibles c'est-à-dire de charger ces classes en mémoire.

  • La tâche suivante consiste à charger les bibliothèques / fichiers JAR externes dans la mémoire pour un fonctionnement correct de l'application. Le ExtClassLoaderest responsable de cette tâche. Ce chargeur de classe est responsable du chargement de tous les fichiers .jar mentionnés dans le chemin java.ext.dirs.

  • Le troisième et le principal chargeur de classe important est le AppClassLoader . Le chargeur de classe d'application est responsable du chargement des fichiers de classe mentionnés dans la propriété système java.class.path.

Il est également important de noter que les implémentations par défaut de ClassLoader peuvent être remplacées, ce qui vous permet de personnaliser la JVM de manière utile et intéressante, vous permettant de redéfinir complètement la façon dont les fichiers de classe sont introduits dans le système.

entrez la description de l'image ici

Consultez-le pour en savoir plus sur Java Class Loader .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.