Ausnahmen beim Laden von Klassen

Welche Art Klassenladefehler wird angezeigt, wenn Sie eine Anwendung entwickeln oder eine installierte Anwendung starten?

ClassCastException

Eine Ausnahme bei der Klassenumsetzung wird generiert, wenn die folgenden Bedingungen vorliegen. Sie kann mit den angegebenen Aktionen behoben werden:

Der Typ des Quellenobjekts ist keine Instanz der Zielklasse (type).
Dies ist die typische Ausnahme bei Klassenumsetzung. Sie können wie folgt diagnostizieren, ob das Quellenobjekt einer Umsetzungsanweisung (cast) keine Instanz der Zielklasse (type) ist. Sie untersuchen die Klassensignatur der Quellenobjektklasse und stellen fest, dass keine ihrer Abstammungsklassen die Zielklasse enthält und dass sich die Quellenobjektklasse von der Zielklasse unterscheidet. Sie können Klasseninformationen abrufen, indem Sie eine einfache Anweisung "print" in Ihren Code einfügen. Beispiel:
System.out.println( source.getClass().getName() + “:” + target.getClass().getName() );
Alternativ dazu können Sie einen javap-Befehl verwenden. Beispiel:
javap java.util.HashMap
Compiled from "HashMap.java"
public class java.util.HashMap extends java.util.AbstractMap
             implements java.util.Map,java.lang.Cloneable,java.io.Serializable {
Der Klassenlader, der das Quellenobjekt (class) geladen hat, ist nicht der Klassenlader, der die Zielklasse geladen hat.
Vorausgesetzt, dass der Typ des Quellenobjekts eine Instanz der Zielklasse ist, tritt eine Ausnahme bei Klassenumsetzung ein, wenn der Klassenlader, der die Klasse des Quellenobjekts geladen hat, nicht der Klassenlader ist, der die Zielklasse geladen hat. Diese Bedingung kann eintreten, wenn die Zielklasse in den Klassenpfaden mehrerer Klassenlader in der Laufzeitumgebung von WebSphere Application Server sichtbar ist. Zur Behebung dieses Fehlers sollten Sie die Konsolseiten zum Suchen und zum Suchen nach Klassennamen verwenden, um Probleme mit Klassenladern zu diagnostizieren:
  1. Klicken Sie auf Fehlerbehebung > Anzeigefunktion für Klassenlader > Modulname > Suchen, um auf die Seite Suchen zuzugreifen.
  2. Wählen Sie als Suchtyp die Option Klasse/Paket aus.
  3. Geben Sie unter Suchbegriffe den Namen der Klasse ein, die von zwei Klassenladern geladen wird.
  4. Klicken Sie auf OK. Die Seite zum Suchen nach Klassennamen wird angezeigt und listet alle Klassenlader auf, die die Klasse laden.

    Wenn mehrere Klassenlader aufgelistet werden, wurde die Zielklasse von mehreren Klassenladern geladen. Da das Quellenobjekt eine Instanz der Zielklasse ist, ist der Klassenlader, der die Klasse des Quellenobjekts geladen hat, nicht mit dem Klassenlader identisch, der die Zielklasse geladen hat.

  5. Kehren Sie zur Seite "Anzeigefunktion für Klassenlader" zurück, und prüfen Sie anhand des Klassenpfads, weshalb die Klasse von zwei unterschiedlichen Klassenladern geladen wird.
  6. Korrigieren Sie den Code, so dass die Klasse nur für den geeigneten Klassenlader sichtbar ist.
Die Anwendung konnte eine narrow-Operation nicht bzw. nicht ordnungsgemäß ausführen.
Eine Ausnahme bei der Klassenumsetzung kann auftreten, wenn der Anwendungscode beim Auflösen eines fernen EJB-Objekts eine erforderliche narrow-Operation nicht ausführt. Die Anwendung muss eine narrow-Operation ausführen, nachdem er ein fernes Objekt gesucht hat. Untersuchen Sie die Anwendung, und stellen Sie fest, ob sie ein fernes Objekt sucht und, wenn ja, ob das Ergebnis der Suchoperation an eine Methode "narrow" übergeben wird.

Die Methode "narrow" muss entsprechend dem Programmiermodell EJB 2.0 aufgerufen werden. Insbesondere die Zielklasse, die an die Methode "narrow" übergeben wird, muss die exakte abgeleitete Schnittstelle der EJB sein. Diese bewirkt ebenfalls eine Ausnahme bei Klassenumsetzung in der Laufzeitumgebung von WebSphere Application Server. Untersuchen Sie die Anwendung, und stellen Sie fest, ob die an die Methode "narrow" übergebene Zielklasse eine Superschnittstelle der angegebenen EJB und nicht der exakte EJB-Typ ist. Sollte dies der Fall sein, ändern Sie die Anwendung so, dass sie die Methode "narrow" mit der exakten EJB-Schnittstelle aufruft.

Wenn während einer narrow-Operation eine Ausnahme bei Klassenumsetzung eintritt, müssen Sie prüfen, ob die Methode "narrow" auf das Ergebnis einer Lookup-Operation für ein fernes EJB-Objekt und nicht auf eine lokale Enterprise-Bean angewendet wird. Für die lokale Suche wird keine narrow-Operation verwendet. Prüfen Sie den Implementierungsdeskriptor für die Anwendung oder für das Modul, um sicherzustellen, dass das Objekt, für das die Operation narrow ausgeführt wird, kein lokales Objekt ist.

ClassNotFoundException

Eine Ausnahme aufgrund einer nicht gefundenen Klasse wird generiert, wenn die folgenden Bedingungen vorliegen. Sie kann mit den angegebenen Aktionen behoben werden:

Die Klasse ist im logischen Klassenpfad des Kontextklassenladers nicht sichtbar.
Die nicht gefundene Klasse ist nicht im logischen Klassenpfad des Klassenladers enthalten, der dem aktuellen Thread zugeordnet ist. Der logische Klassenpfad ist die Zusammenstellung aller Klassenpfade, die durchsucht werden, wenn eine Ladeoperation in einem Klassenlader aufgerufen wird. Zur Behebung dieses Problems verwenden Sie die Seite "Suche", um nach Klassennamen und nach JAR-Namen (Java™-Archiv) zu suchen:
  1. Klicken Sie auf Fehlerbehebung > Anzeigefunktion für Klassenlader > Modulname > Suchen, um auf die Seite Suchen zuzugreifen.
  2. Wählen Sie als Suchtyp die Option Klasse/Paket aus.
  3. Geben Sie unter Suchbegriffe den Namen der Klasse ein, die nicht gefunden wird.
  4. Klicken Sie auf OK. Die Seite zum Suchen nach Klassennamen wird angezeigt und listet alle Klassenlader auf, die die Klasse laden.
  5. Prüfen Sie, ob die Klasse in der Liste auf der Seite angegeben ist.
  6. Ist die Klasse nicht in der Liste enthalten, kehren Sie zur Seite "Suchen" zurück. Geben Sie unter Suchbegriffe den Namen der Datei mit der Erweiterung .jar für die Klasse ein. Wählen Sie als Suchtyp die Option JAR/Verzeichnis aus.
  7. Klicken Sie auf OK. Die Seite zum Suchen nach dem Pfad wird angezeigt und listet alle Verzeichnisse auf, die die JAR-Datei enthalten.

Ist die JAR-Datei nicht in der Liste enthalten, befindet sich die Klasse wahrscheinlich nicht im logischen Klassenpfad, ist nicht lesbar, oder eine alternative Klasse ist bereits geladen. Verschieben Sie die Klasse in einen Pfad, aus dem sie geladen werden kann.

Die Anwendung verwendet eine Klassenlader-API nicht ordnungsgemäß.
Eine Anwendung kann eine Instanz eines Klassenladers abrufen und entweder die Methode "loadClass" in diesem Klassenlader oder Class.forName(Klassenname, initialize, Klassenlader) mit diesem Klassenlader aufrufen. Die Anwendung verwendet möglicherweise die Anwendungsprogrammierschnittstelle (API) des Klassenladers nicht ordnungsgemäß. Der Klassenname ist möglicherweise falsch, die Klasse ist im logischen Klassenpfad dieses Klassenladers nicht sichtbar, oder es wurde der falsche Klassenlader verwendet.

Zur Behebung dieses Problems ermitteln Sie, ob die Klasse existiert und ob die Anwendung die Klassenlader-API ordnungsgemäß verwendet. Führen Sie die Schritte im Abschnitt Die Klasse ist im logischen Klassenpfad des Kontextklassenladers nicht sichtbar aus, um festzustellen, ob die Klasse geladen ist. Wurde die Klasse nicht geladen, versuchen Sie, die Anwendung zu korrigieren, und prüfen Sie erneut, ob die Klasse geladen wird. Wenn sich die Klasse im Klassenpfad mit der richtigen Berechtigung befindet und von keiner anderen Factory-Klasse überschrieben wird, prüfen Sie die API, mit der die Klasse geladen wird.

  1. Klicken Sie auf Fehlerbehebung > Anzeigefunktion für Klassenlader > Modulname > Suchen, um die Seite Suchen für Klassenlader aufzurufen.
  2. Wählen Sie als Suchtyp die Option Klasse/Paket aus.
  3. Geben Sie unter Suchbegriffe den Namen der Klasse ein.
  4. Klicken Sie auf OK. Die Seite zum Suchen nach Klassennamen wird angezeigt und listet alle Klassenlader auf, die die Klasse laden.
  5. Prüfen Sie, ob die Klasse in der Liste auf der Seite angegeben ist.
  6. Ist die Klasse in der Liste enthalten und wurde die Ausnahme "ClassNotFound" ausgelöst, dann befindet sich die .jar-Datei oder die Klasse nicht im richtigen Kontext oder im aktuellen Kontext wurde ein falscher API-Aufruf verwendet.
    Ist die Klasse nicht in der Liste enthalten, kehren Sie zur Seite "Suchen" zurück, und gehen Sie wie folgt vor:
    1. Suchen Sie die Klasse, die die Ausnahme generiert hat, d. h. die Klasse, die Class.forName aufruft.
    2. Prüfen Sie, von welchem Klassenlader die Klasse geladen wird.
    3. Prüfen Sie den Klassenpfad im Klassenlader, um festzustellen, ob der Klassenlader Zugriff auf die Klasse hat, die nicht gefunden wurde, oder ob er diese Klasse laden kann.
Eine abhängige Klasse ist nicht sichtbar.
Wenn ein Klassenlader clsldr eine Klasse cls lädt, ruft die Java Virtual Machine (JVM) clsldr auf, um die Klassen zu laden, von denen cls abhängig ist. Abhängige Klassen müssen im logischen Klassenpfad von clsldr sichtbar sein, andernfalls tritt eine Ausnahme ein. Diese Bedingung tritt normalerweise ein, wenn Benutzer WebSphere Application Server-Klassen oder Anwendungsklassen für die JVM oder für den Klassenlader für WebSphere-Erweiterungen sichtbar machen. Beispiel:
  • Klasse A ist abhängig von Klasse B.
  • Klasse A ist sichtbar für den Klassenlader für WebSphere-Erweiterungen.
  • Klasse B ist im lokalen Klassenpfad des Klassenladers für ein WAR-Modul und nicht im Klassenpfad des Klassenladers für WebSphere-Erweiterungen sichtbar.

Wenn die JVM Klasse A mit dem Klassenlader für WebSphere-Erweiterungen lädt, versucht sie, Klasse B mit demselben Klassenlader zu laden und löst schließlich eine Ausnahme des Typs "Klasse nicht gefunden" aus.

Gehen Sie wie folgt vor, um diesen Fehler zu beheben:

  1. Machen Sie die anwendungsspezifischen Klassen für den entsprechenden Anwendungsklassenlader sichtbar.
  2. Suchen Sie nach der Klasse, die nicht gefunden wurde (Klasse B).
  3. Wenn sich Klasse B an der richtigen Position befindet, suchen Sie in der Anzeigefunktion für Klassenlader nach der Klasse, die die abhängige Klasse (Klasse A) lädt.
  4. Ist die Klasse geladen und wurde die Ausnahme "ClassNotFound" ausgelöst, dann befindet sich die .jar-Datei oder die Klasse nicht im richtigen Kontext oder im aktuellen Kontext wurde ein falscher API-Aufruf verwendet.
    Wurde keine Klasse gefunden, gehen Sie wie folgt vor:
    1. Suchen Sie die Klasse, die die Ausnahme generiert hat, d. h. die Klasse, die Class.forName aufruft.
    2. Prüfen Sie, von welchem Klassenlader die Klasse geladen wird.
    3. Prüfen Sie den Klassenpfad im Klassenlader, um festzustellen, ob der Klassenlader Zugriff auf die Klasse hat, die nicht gefunden wurde, oder ob er diese Klasse laden kann.
  5. Vergewissern Sie sich, dass die aufrufende Klasse (Klasse B) für die JVM oder für den Klassenlader für WebSphere-Erweiterungen sichtbar ist.

NoClassDefFoundException

Eine Ausnahme aufgrund einer nicht gefundenen Klassendefinition wird generiert, wenn die folgenden Bedingungen vorliegen. Sie kann mit den angegebenen Aktionen behoben werden:

Die Klasse ist nicht im logischen Klassenpfad enthalten.
Nähere Informationen hierzu finden Sie im Artikel ClassNotFoundException.
Die Klasse kann nicht geladen werden.
Es gibt verschiedene Gründe dafür, dass eine Klasse nicht geladen wird. Folgende Gründe sind möglich: Eine abhängige Klasse konnte nicht geladen werden, die abhängige Klasse hat das falsche Format oder die Klasse wird aufgrund ihrer Versionsnummer nicht geladen.

UnsatisfiedLinkError

Ein Verbindungsfehler wird generiert, wenn die folgenden Bedingungen vorliegen. Er kann mit den angegebenen Aktionen behoben werden:

Eine Benutzeraktion hat den Fehler verursacht.

Es gibt mehrere Benutzeraktionen, die einen Verbindungsfehler verursachen können:

Ein Bibliothekserweiterungsname ist für die Plattform nicht korrekt.

[Windows]Eine Bibliothek hat DLL-Namen Bibliotheksname.dll.

[AIX HP-UX Solaris]Eine Bibliothek hat den Namen Bibliotheksname.so bzw. Bibliotheksname.a.

An System.loadLibrary wird ein falscher Parameter übergeben.

[Windows]Damit eine DLL mit dem Namen Name.dll geladen wird, muss Name an einen loadLibrary-Aufruf übergeben werden.

[AIX HP-UX Solaris]Damit eine Bibliothek mit dem Namen libName.so oder libName.a übergeben wird, muss libName an die Ladebibliothek übergeben werden.

Die Bibliothek ist nicht sichtbar.
Es wird empfohlen, den JVM-Klassenlader zu verwenden, um native Bibliotheken zu suchen und zu laden. WebSphere Application Server gibt den Java-Bibliothekspfad (java.library.path) während des Startvorgangs aus. Wenn der JVM-Klassenlader die Bibliothek laden sollen, müssen Sie sicherstellen, dass der Pfad mit der nativen Bibliotheksdatei im Java-Bibliothekspfad enthalten ist. Wenn nicht, fügen Sie den Pfad zur plattformspezifischen Umgebungsvariablen für native Bibliotheken oder zur Systemeigenschaft java.library.path der Serverprozessdefinition hinzu.

Die JVM ruft im Allgemeinen die Methode "findLibrary()" im Klassenlader xxx auf, der die Klasse lädt, mit der "System.loadLibrary()" aufgerufen wird. Wenn xxx.findLibrary() fehlschlägt, versucht die JVM, die Bibliothek mithilfe des JVM-Klassenladers zu finden, der den JVM-Bibliothekspfad durchsucht. Wenn die Bibliothek nicht gefunden werden kann, generiert die JVM eine Ausnahme des Typs UnsatisfiedLinkError.

Wenn ein WebSphere-Klassenlader eine native Bibliothek meineNativeBib finden soll, muss die Bibliothek im nativelibpath des Klassenladers sichtbar sein, der die Klasse lädt, die System.loadLibrary(myNativeBib) aufruft. Diese Vorgehensweise ist in der folgenden Situation erforderlich bzw. empfehlenswert:

  • [z/OS]Native Bibliotheken für Datenquellenprovider müssen im nativelibpath des Klassenladers für WebSphere-Erweiterungen sichtbar sein. In diesem Fall müssen Sie den Pfad mit der nativen Bibliothek zur Einstellung Nativer Bibliothekspfad in der Konfiguration des Datenquellenproviders hinzufügen.
  • Gemeinsam genutzte Bibliotheken haben einen Nativen Bibliothekspfad in ihrer Konfiguration. Da gemeinsam genutzte Bibliotheken die Versionssteuerung anwendungsspezifischer Bibliotheken unterstützen, sollten Sie die Pfade zu allen nativen Bibliotheken angeben, die vom Code für gemeinsam genutzte Bibliotheken in der Konfiguration für gemeinsam genutzte Bibliotheken verwendet werden.

Vergewissern Sie sich, dass die Klasse, mit der "System.loadLibrary()" aufgerufen wird, vom richtigen WebSphere-Klassenlader geladen wird und dass die native Bibliothek in der Einstellung Nativer Bibliothekspfad sichtbar ist.

[AIX HP-UX Solaris]
System.mapLibraryName gibt die falsche Bibliotheksdatei zurück.
Beim Laden einer gemeinsam genutzten Bibliothek ruft die JVM mapLibraryName(libName) auf, um den Bibliotheksnamen (libName) in einen plattformspezifischen Namen umzuwandeln. In den Betriebssystemen AIX, HP-UX und Solaris kann dieser Aufruf einen Dateinamen mit der falschen Erweiterung zurückgeben (z. B. libName.so und nicht libName.a). Zur Behebung dieses Fehlers schreiben Sie ein Programm, das System.mapLibraryName() aufruft, und vergewissern Sie sich, dass dieses Programm den richtigen Dateinamen zurückgibt.
Die native Bibliothek ist bereits geladen.
Diese Bedingung kann durch einen der folgenden Fehler verursacht werden:
Benutzerfehler
Prüfen Sie, ob mehrere Aufrufe an System.loadLibrary abgesetzt werden, und entfernen Sie überflüssige Aufrufe.
Fehler beim Neustart einer Anwendung
Die JVM hat die Einschränkung, dass nur jeweils ein Klassenlader eine native Bibliothek laden kann. Es tritt ein Fehler auf, wenn eine Anwendung erneut gestartet wird, bevor der Garbage-Collector den Klassenlader aus der gestoppten Anwendung bereinigt hat. Wenn die Klasse, die die native Bibliothek lädt, verschoben wird, müssen auch alle Klassen, die von dieser nativen Bibliothek abhängig sind, und ihre Abhängigkeiten verschoben werden.

Sie können diese Bedingung korrigieren, indem Sie das Laden der nativen Bibliothek in einen Klassenlader verlagern, der nicht erneut geladen wird:

  1. Suchen Sie alle Anwendungsklassen, die native Bibliotheken laden oder native Methoden enthalten.
  2. Identifizieren Sie alle abhängigen Klassen für die Klassen aus Schritt 1, z. B. Pakete für die Protokollierung.
  3. Erstellen Sie eine dem Server zugeordnete gemeinsam genutzte Bibliothek oder eine isolierte gemeinsam genutzte Bibliothek.
  4. Verschieben Sie alle JAR-Dateien, die für die Klassen aus Schritt 1 und 2 geladen werden, aus der Anwendung in die in Schritt 3 erstellte gemeinsam genutzte Bibliothek.
  5. Speichern Sie Ihre Änderungen.
  6. Implementieren Sie die Anwendung erneut, und wiederholen Sie das Szenario.

Klassen in Bibliotheken, deren Geltungsbereich der Server ist, werden für jeden Serverlebenszyklus einmal geladen, wobei sichergestellt wird, dass die von der Anwendung benötigte native Bibliothek für jede JVM einmal geladen wird, unabhängig vom Lebenszyklus der Anwendung.

Eine abhängige native Bibliothek wurde verwendet.
Abhängige native Bibliotheken müssen mit dem JVM-Klassenlader gesucht oder geladen werden. Dies bedeutet Folgendes: Wenn eine native Bibliothek mit dem Namen NL abhängig ist von einer anderen nativen Bibliothek mit dem Namen DNL, dann muss der JVM-Klassenlader DNL im Java-Bibliothekspfad suchen. Dies liegt daran, dass die JVM beim Laden von NL nativen Code ausführt. Wenn der native JVM-Code eine Abhängigkeit von DNL feststellt, kann er lediglich den JVM-Klassenlader aufrufen, damit er diese Abhängigkeit auflöst. Ein WebSphere-Klassenlader kann keine abhängige native Bibliothek laden.

Ändern Sie die plattformspezifische Umgebungsvariable, die den Java-Bibliothekspfad (LIBPATH) definiert so, dass sie den Pfad mit der nicht aufgelösten nativen Bibliothek enthält.


Symbol, das den Typ des Artikels anzeigt. Referenzartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=rtrb_classload_viewer
Dateiname:rtrb_classload_viewer.html