Frage

Wer weiß, wie programmaticly um herauszufinden, wo die Java-Classloader eigentlich die Klasse von Lasten?

ich oft an großen Projekten arbeiten, wo der Classpath sehr lang wird und die manuelle Suche ist nicht wirklich eine Option. Ich hatte vor kurzem ein Problem wo die Classloader eine falsche Version von a geladen wurden Klasse, weil es auf dem classpath an zwei verschiedenen Orten war.

Wie kann ich die Klassenlader zu bekommen, mir zu sagen, wo auf der Festplatte der tatsächliche Klassendatei herkommt?

Edit: Was ist, wenn der Klassenlader nicht tatsächlich die Klasse aufgrund einer Versionskonflikt (oder etwas anderes) zu laden, gibt es trotzdem können wir herausfinden, welche Datei zu lesen sein versuchen, bevor er es liest?

War es hilfreich?

Lösung

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"));
    }
}

Dieses ausgedruckt:

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

Andere Tipps

Ein weiterer Weg, um herauszufinden, wo eine Klasse von geladen wird (ohne die Quelle zu manipulieren) ist den Java-VM mit der Option zu starten: -verbose:class

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

Dies ist, was wir verwenden:

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

Dies funktioniert auf der Classloader Implementierung abhängig: getClass().getProtectionDomain().getCodeSource().getLocation()

Jon-Version schlägt fehl, wenn das Objekt ClassLoader als null registriert ist die, dass sie von der Boot ClassLoader geladen wurde zu implizieren scheint.

Dieses Verfahren befasst sich mit diesem Thema:

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(".", "/") + ".class");
    if ( resource != null ) {
      return resource.toString();
    }
  }
  return "Unknown";
}

Bearbeiten nur 1. Zeile: Main.class

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!

Werfen Sie einen Blick auf diese ähnliche Frage. Werkzeug derselben Klasse zu entdecken ..

Ich denke, das wichtigste Hindernis ist, wenn Sie einen benutzerdefinierten Classloader haben (Laden von einem db oder ldap)

Normalerweise wir nicht, was Hardcoding zu verwenden. Wir können classname erhalten zuerst, und dann Classloader verwenden, um die Klasse URL zu erhalten.

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

Dieser Ansatz funktioniert für beide Dateien und Gläser:

Class clazz = Class.forName(nameOfClassYouWant);

URL resourceUrl = clazz.getResource("/" + clazz.getCanonicalName().replace(".", "/") + ".class");
InputStream classStream = resourceUrl.openStream(); // load the bytecode, if you wish

Unter der Annahme, dass Sie mit einer Klasse mit dem Namen MyClass arbeiten, sollte folgende Arbeiten:

MyClass.class.getClassLoader();

Unabhängig davon, ob Sie den On-Disk-Standort der .class-Datei selbst auf dem Classloader abhängig zu bekommen. Zum Beispiel, wenn Sie so etwas wie BCEL verwenden, kann eine bestimmte Klasse hat nicht einmal eine On-Disk-Darstellung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top