Finden Sie heraus, woher die Java-Klasse geladen wird

Lesezeit: 4 Minuten

Finden Sie heraus woher die Java Klasse geladen wird
Lukas

Weiß jemand, wie man programmgesteuert herausfinden kann, woher der Java-Classloader die Klasse tatsächlich lädt?

Ich arbeite oft an großen Projekten, bei denen der Klassenpfad sehr lang wird und eine manuelle Suche nicht wirklich eine Option ist. Ich hatte kürzlich ein Problem, bei dem der Klassenlader eine falsche Version einer Klasse geladen hat, weil sie sich an zwei verschiedenen Stellen im Klassenpfad befand.

Wie kann ich also den Classloader dazu bringen, mir mitzuteilen, wo auf der Festplatte die eigentliche Klassendatei herkommt?

Bearbeiten: Was ist, wenn der Classloader die Klasse aufgrund eines Versionskonflikts (oder etwas anderem) tatsächlich nicht lädt, können wir trotzdem herausfinden, welche Datei versucht wird, zu lesen, bevor er sie liest?

Hier ist ein Beispiel:

package foo;

public class Test
{
    public static void main(String[] args)
    {
        ClassLoader loader = Test.class.getClassLoader();
        System.out.println(loader.getResource("foo/Test.class"));
    }
}

Das ausgedruckt:

file:/C:/Users/Jon/Test/foo/Test.class

  • Um überflüssiges Tippen zu vermeiden, kann man auch die kürzere Version verwenden: Test.class.getResource("Test.class")die den Paketnamen nicht wiederholt.

    – Verdienst

    1. Februar 2013 um 16:42 Uhr


  • Was ist, wenn die Klasse kompiliert wird, zB aus einer .groovy-Datei?

    – Ondra Žižka

    28. Juni 2013 um 0:58 Uhr

  • @meriton: Oder um Refactorings zu überleben: Test.class.getResource(Test.class.getSimpleName() + ".class")

    – Leonbloy

    21. Juli 2013 um 16:50 Uhr

  • Zum BouncyCastleProvider Der vollständige Paketname ist jedoch erforderlich.

    – Pawel Wlassow

    7. November 2013 um 13:34 Uhr

  • Es ist möglich für getClassLoader() zurückgeben null. Siehe hier für eine Erweiterung dieser Methode, um damit umzugehen.

    – Alter Geizhals

    4. Januar 2014 um 10:47 Uhr

1646254026 506 Finden Sie heraus woher die Java Klasse geladen wird
jiriki

Eine andere Möglichkeit herauszufinden, woher eine Klasse geladen wird (ohne die Quelle zu manipulieren), besteht darin, die Java VM mit der Option zu starten: -verbose:class

  • Dies funktionierte sehr gut und hat nicht das Problem, mit Klassen mit null ClassLoader umzugehen

    – lexikalischer Umfang

    9. September 2011 um 11:58 Uhr

  • @ries Wenn man dies nicht programmgesteuert tun muss, ist dies definitiv der richtige Weg, und es hat mein Problem gelöst. Das OP hatte jedoch speziell gefragt, wie dies programmgesteuert erfolgen soll.

    – SantiBailors

    17. Februar 2017 um 16:09 Uhr

1646254026 387 Finden Sie heraus woher die Java Klasse geladen wird
Dave DiFranco

getClass().getProtectionDomain().getCodeSource().getLocation();

  • Ja, obwohl es mit einem installierten Sicherheitsmanager und ohne die erforderlichen Berechtigungen nicht funktioniert.

    – Tom Hawtin – Angelleine

    23. Oktober 2008 um 13:35 Uhr

  • FYI, NPE = Null-Zeiger-Ausnahme. HTH!

    – Jewgeni Sergejew

    19. November 2015 um 9:40 Uhr

  • Diese Methode wird bevorzugt, solange Sie einen Verweis auf eine Instanz haben, da Sie dieselbe Klasse von zwei verschiedenen Orten laden können.

    – Miguel Ping

    24. Juli 2017 um 10:04 Uhr

  • Funktioniert auch nicht, wenn es von einem Java 9+ Modul aufgerufen wird (was man 2008 natürlich nicht wissen konnte).

    – Jeff G

    30. September 2018 um 20:40 Uhr


Finden Sie heraus woher die Java Klasse geladen wird
Jewgeni Kabanow

Das verwenden wir:

public static String getClassResource(Class<?> klass) {
  return klass.getClassLoader().getResource(
     klass.getName().replace('.', "https://stackoverflow.com/") + ".class").toString();
}

Dies funktioniert abhängig von der ClassLoader-Implementierung:
getClass().getProtectionDomain().getCodeSource().getLocation()

1646254027 262 Finden Sie heraus woher die Java Klasse geladen wird
Alter Geizhals

Jons Version schlägt fehl, wenn die des Objekts ClassLoader ist registriert als null was darauf hinzudeuten scheint, dass es vom Boot geladen wurde ClassLoader.

Diese Methode befasst sich mit diesem Problem:

public static String whereFrom(Object o) {
  if ( o == null ) {
    return null;
  }
  Class<?> c = o.getClass();
  ClassLoader loader = c.getClassLoader();
  if ( loader == null ) {
    // Try the bootstrap classloader - obtained from the ultimate parent of the System Class Loader.
    loader = ClassLoader.getSystemClassLoader();
    while ( loader != null && loader.getParent() != null ) {
      loader = loader.getParent();
    }
  }
  if (loader != null) {
    String name = c.getCanonicalName();
    URL resource = loader.getResource(name.replace(".", "https://stackoverflow.com/") + ".class");
    if ( resource != null ) {
      return resource.toString();
    }
  }
  return "Unknown";
}

Bearbeiten Sie nur die erste Zeile: Main.Klasse

Class<?> c = Main.class;
String path = c.getResource(c.getSimpleName() + ".class").getPath().replace(c.getSimpleName() + ".class", "");

System.out.println(path);

Ausgabe:

/C:/Users/Test/bin/

Vielleicht schlechter Stil, aber funktioniert gut!

Finden Sie heraus woher die Java Klasse geladen wird
Hongyang

Normalerweise verwenden wir keine Hardcoding. Wir können zuerst className abrufen und dann ClassLoader verwenden, um die Klassen-URL abzurufen.

        String className = MyClass.class.getName().replace(".", "https://stackoverflow.com/")+".class";
        URL classUrl  = MyClass.class.getClassLoader().getResource(className);
        String fullPath = classUrl==null ? null : classUrl.getPath();

  • Muss lauten: URL classUrl = MyClass.class.getClassLoader().getResource(“/” + className);

    – Andreas Coates

    6. Januar 2020 um 15:04 Uhr

  • MyClass.class ist ein wichtiger Teil – getClass() kann Proxy zurückgeben! Dann können Sie einen Namen wie MyClass$$EnhancerBySpringCGLIB$$a98db882.class und eine Null-URL erhalten.

    – jalmasi

    13. Februar 2020 um 15:33 Uhr

915990cookie-checkFinden Sie heraus, woher die Java-Klasse geladen wird

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy