Wir stoßen häufig auf ClassNotFound-Ausnahmen, die darauf hinweisen, dass beim Versuch, eine Klasse zu laden, ein Fehler der JVM aufgetreten ist. Um diese Ausnahme zu lösen, müssen Sie wissen
Überlegen Sie, wie Tomcat Servlets unter Webanwendungen lädt und verwaltet? JVM-KlassenladerBeim Laden von Java-Klassen wird die Datei im Bytecode-Format .class in den Methodenbereich der JVM geladen und eine Instanz des Objekts java.lang.Class im JVM-Heap erstellt, um die mit der Java-Klasse verbundenen Daten und Methoden zu kapseln. Was ist ein Class-Objekt? Die JVM lädt nicht alle .class-Dateien beim Start, sondern lädt die Klasse erst, wenn das Programm im laufenden Betrieb verwendet wird. öffentliche abstrakte Klasse ClassLoader { //Jeder Klassenlader hat einen übergeordneten Loader private final ClassLoader parent; öffentliche Klasse<?> loadClass(Stringname) { // Herausfinden, ob die Klasse geladen wurde Class<?> c = findLoadedClass(name); // Wenn es nicht geladen wurde if( c == null ){ // [Rekursion] Delegieren Sie an den übergeordneten Loader zum Laden, wenn (übergeordnet != null) { c = übergeordnetes Element.loadClass(Name); } anders { // Wenn der übergeordnete Loader leer ist, ermitteln Sie, ob der Bootstrap Loader geladen wurde c = findBootstrapClassOrNull(name); } } // Wenn das Laden des übergeordneten Loaders fehlschlägt, rufe seine eigene findClass zum Laden auf, if (c == null) { c = Klasse finden(Name); } Rückkehr c; } geschützte Klasse<?> findClass(Stringname){ // 1. Suchen Sie anhand des übergebenen Klassennamens nach der Klassendatei in einem bestimmten Verzeichnis und lesen Sie die .class-Datei in den Speicher ein … // 2. Rufen Sie defineClass auf, um das Byte-Array in ein Class-Objekt umzuwandeln. return defineClass(buf, off, len); } // Analysieren Sie das Bytecode-Array in ein Class-Objekt und implementieren Sie es mit nativen Methoden protected final Class<?> defineClass(byte[] b, int off, int len){ ... } } Die Klassenlader der JVM sind hierarchische Eltern-Kind-Beziehungen und jeder Klassenlader enthält ein Elternfeld, das auf den Elternlader verweist.
loadClass prüft zunächst, ob die Klasse geladen wurde. Wenn ja, wird sie direkt zurückgegeben, andernfalls wird sie zum Laden an den übergeordneten Loader übergeben. Das Funktionsprinzip des JDK-Klassenladers ist dasselbe. Der einzige Unterschied besteht im Ladepfad, d. h. der von findClass gesuchte Pfad ist anders. Die Eltern-Kind-Beziehung von Klassenladern wird nicht durch Vererbung implementiert. Beispielsweise ist AppClassLoader keine Unterklasse von ExtClassLoader, aber das übergeordnete Objekt von AppClassLoader zeigt auf das ExtClassLoader-Objekt. Tomcat-Klassenlader Tomcats benutzerdefinierter Klassenlader „WebAppClassLoader“ unterbricht den übergeordneten Delegierungsmechanismus: Klasse findenöffentliche Klasse<?> findClass(String name) löst ClassNotFoundException { aus ... Klasse<?> clazz = null; versuchen { //1. Suchen Sie zuerst im Web-Anwendungsverzeichnis nach der Klasse clazz = findClassInternal(name); } Fang (RuntimeException e) { werfen e; } wenn (clazz == null) { versuchen { //2. Wenn im lokalen Verzeichnis nicht gefunden, lassen Sie den übergeordneten Loader suchen clazz = super.findClass(name); } Fang (RuntimeException e) { werfen e; } //3. Wenn die übergeordnete Klasse nicht gefunden wird, werfen Sie ClassNotFoundException wenn (clazz == null) { wirf eine neue ClassNotFoundException(Name); } Rückgabeklazz; } Workflow
Ladeklasseöffentliche Klasse<?> loadClass(Stringname, Boolesche Auflösung) wirft ClassNotFoundException { synchronisiert (getClassLoadingLock(name)) { Klasse<?> clazz = null; //1. Prüfen Sie zunächst im lokalen Cache, ob die Klasse geladen wurde. clazz = findLoadedClass0(name); if (clazz != null) { wenn (auflösen) Klasse auflösen(clazz); Rückgabeklazz; } //2. Prüfen Sie, ob der Systemklassenlader clazz = findLoadedClass(name); geladen hat. if (clazz != null) { wenn (auflösen) Klasse auflösen(clazz); Rückgabeklazz; } // 3. Versuchen Sie, die Klasse mit dem Klassenlader ExtClassLoader zu laden. Warum? Ich habe versucht, den ClassLoader zu starten, aber ich habe ihn nicht gestartet. versuchen { clazz = javaseLoader.loadClass(name); if (clazz != null) { wenn (auflösen) Klasse auflösen(clazz); Rückgabeklazz; } } Fang (ClassNotFoundException e) { // Ignorieren } // 4. Versuche die Klasse im lokalen Verzeichnis zu suchen und zu laden try { clazz = Klasse finden(Name); if (clazz != null) { wenn (auflösen) Klasse auflösen(clazz); Rückgabeklazz; } } Fang (ClassNotFoundException e) { // Ignorieren } // 5. Versuchen Sie, den Systemklassenlader (d. h. AppClassLoader) zum Laden zu verwenden try { clazz = Klasse.forName(Name, falsch, übergeordnetes Element); if (clazz != null) { wenn (auflösen) Klasse auflösen(clazz); Rückgabeklazz; } } Fang (ClassNotFoundException e) { // Ignorieren } } //6. Das Laden der oben genannten Prozesse schlägt fehl und es wird eine Ausnahme ausgelöst: throw new ClassNotFoundException(name); } Workflow
Es ist ersichtlich, dass der Tomcat-Klassenlader die übergeordnete Delegierung unterbricht und zu Beginn nicht direkt an den übergeordneten Lader delegiert, sondern ihn zuerst in das lokale Verzeichnis lädt. Dies ist das Ende dieses Artikels darüber, wie Tomcat den übergeordneten Delegationsmechanismus unterbricht. Weitere Informationen zum übergeordneten Delegationsmechanismus von Tomcat finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Tatsächlicher Datensatz zur Wiederherstellung der MySQL-Datenbank nach Zeitpunkt
Einführung Es ist nicht nötig, Redis im Detail vo...
Zusätzliche Erklärung, Fremdschlüssel: Verwenden ...
Gut funktionierende Einstellungen für Tabelleneige...
Fügen Sie dem el-form-Formular Regeln hinzu: Defi...
Kürzlich habe ich ein Spark-Streaming-Programm in...
Nachfragehintergrund Als statistische Schnittstel...
In diesem Artikel wird der spezifische Code von V...
Hintergrund Da die Anzahl der Unterprojekte des U...
In diesem Artikelbeispiel wird der spezifische Co...
Ich habe mein Blog seit mehreren Tagen nicht aktu...
1. Gehen Sie zur offiziellen GraphVis-Website, um...
In diesem Artikel werden hauptsächlich kreisförmi...
In diesem Artikelbeispiel wird der spezifische Co...
1. Öffnen Sie Port 2375 Bearbeiten Sie docker.ser...
01. Übersicht Absolute und relative Pfade kommen ...