2016-09-19 16 views
0

Ich versuche, einen benutzerdefinierten Classloader zum Laden zufälliger .class Dateien, die sich irgendwo im Dateisystem befinden können, zu verwenden. Ich schrieb meinen Klassenlader, um ClassLoader zu erweitern, überschrieb die Methoden findClass() und loadClass() und las den Byte-Stream der Klassendatei ein. Das Problem entsteht, wenn ich ClassLoader.defineClass()Problemumgehung NoClassDefFoundError für falsche Verzeichnisstruktur

Die genaue Fehlermeldung erhalten aufzurufen versuchen, ist:

Exception in thread "main" java.lang.NoClassDefFoundError: Test (wrong name: com/foo/bar/Test) 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800) 

Ich weiß, dass das Problem ist, dass die native Classloading Funktion nicht die Tatsache mag, dass Test.class nicht lebt /someDir/com/foo/bar/. Kann ich das irgendwie machen? Mein Classloader verfügt bereits über Code, um zu überprüfen, ob die definierte Klasse einem bestimmten Paket entspricht. Ich verstehe wirklich nicht, warum die native Methode dies nicht zulassen würde (abgesehen von der Sicherheit, die ich in diesem Anwendungsfall nicht brauche, und Event, dann lass mich in den Fuß schießen).

+0

Haben Sie die Kontrolle über die zu ladende Klasse und können diese ändern? Wenn ja, ist der Paketname erforderlich? Wenn nicht, definieren Sie einfach keinen Paketnamen, dann sollten Sie in der Lage sein, die Klasse aus einem beliebigen Verzeichnis zu laden. Der Paketname ist eigentlich ein Teil der Klasse und erfordert daher bestimmte Byte-Manualisierungs-Frameworks wie [Javassist] (http://jboss-javassist.github.io/javassist/), um die Bytes zu laden und dann die "Klassen" -Darstellung vorher zu aktualisieren tatsächliches Laden über einen Classloader. –

+0

Später finde ich alle geladenen Klassen in einem bestimmten Paket, also verlasse ich mich darauf, dass der Paketname etwas bestimmtes ist. ID möchte jedoch diese Klassendatei in der Verzeichnisstruktur an beliebiger Stelle platzieren und trotzdem laden. – bss36504

+0

Dann werfen Sie einen Blick auf Javassit (oder ein anderes Byte-Manipulations-Framework) –

Antwort

1

Native Klasse Loader, d. H. ClassLoader.defineClass1, weiß nichts über Verzeichnisstruktur. Es lädt nur ein Byte-Array.

Die Fehlermeldung besagt, dass der als Argument an defineClass übergebene Binärname nicht mit dem tatsächlich aus den Klassendatenbytes ermittelten Namen übereinstimmt. Die einfachste Problemumgehung besteht darin, name=null beim Aufrufen von defineClass festzulegen.

Hinweis: Sie können ein Paket einer Klasse nicht ändern, indem Sie es einfach in ein anderes Verzeichnis verschieben. Der Paketname ist in Klassendateidaten eingebettet. Sie müssen die Quellen entweder mit der richtigen package Direktive neu kompilieren oder die Klassendatei-Bytes beim Laden mit dem Bytecode-Instrumentierungsframework ändern.

+0

Wow, ich kann nicht glauben, dass es so einfach war. Das scheint zu funktionieren, vielen Dank! – bss36504

Verwandte Themen