2016-06-18 5 views
6

Ich habe den folgenden Code:Javassist NotFoundException wenn immer java.io.Serializable mit JDK9

private static CtClass resolveCtClass(String clazz) throws NotFoundException { 
    ClassPool pool = ClassPool.getDefault(); 
    return pool.get(clazz); 
} 

Wenn unter JDK8 ausgeführt wird, wenn diese Methode java.io.Serializable aufgerufen wird, es funktioniert, aber wenn sie unter dem JDK9-Umgebung ausgeführt wird wirft es die NotFoundException.

Gibt es etwas, das ich hier übersehen habe?

Antwort

6

Dies passiert nicht mehr mit den aktuellen EA-Builds von Java 9. Klassendateien sind jetzt immer lokalisierbar, auch wenn sie in einem Modul gekapselt sind.

Dies ist eine Konsequenz der Modulkapselung von Java 9, bei der nicht exportierte Ressourcen nicht mehr über die API ClassLoader verfügbar sind. Unter den Abdeckungen, ruft Javassist

ClassLoader.getSystemClassLoader().findResource("java/io/Serializable.class"); 

für Serializable halten, die Klassendatei zu erhalten. Anschließend analysiert es diese Klassendatei und stellt die Informationen ähnlich wie die Java-Reflektions-API dar, ohne jedoch die Klasse so zu laden, dass sie vor dem Laden editiert werden kann.

Bis auf Java 8 war diese Klassendatei verfügbar, da die meisten Klassenlader darauf angewiesen sind, eine Klassendatei vor dem Laden zu suchen, sodass der obige Aufruf eine URL zurückgab, die auf die Datei verweist. Seit Java 9 sind Ressourcen von benannten Modulen nur über die neue API-Methode findResource(String, String) verfügbar, wobei die zweiten Argumente das Modul dieser Klasse benennen.

Die kurze Antwort ist: Javassist funktioniert nicht mehr mit Java 9 und keiner von its dependant projects wird. Dies ist ein known issue mit der aktuellen Java 9-Implementierung und wird hoffentlich vor der Veröffentlichung behoben werden.

1

(Ich habe nie Javassist so bin ich nur Aufnahmen im Dunkeln, hier ...)

Die documentation of ClassPool sagt:

Wenn get() auf dieses Objekt aufgerufen wird, sucht es verschiedene Quellen dargestellt durch ClassPath, um eine Klassendatei zu finden, und erzeugt dann ein CtClass Objekt, das diese Klassendatei darstellt.

Dies scheint an das Konzept des Klassenpfads gebunden zu sein. Ein Blick auf ClassPath und CtClass unterstützt diese Annahme.

Wenn das der Fall ist, dann könnte Javassist einfach nicht fit in JDK 9 brandneuen modules aussehen.

Wenn meine Vermutung richtig ist, sollten Sie keine JDK-Klasse aus dem Pool erhalten. Dies sollte leicht überprüfbar sein.

Verwandte Themen