Die einzige Möglichkeit, eine Klasse zu entladen, besteht darin, dass der verwendete Classloader Müllsammlung ist. Dies bedeutet, dass Verweise auf jede einzelne Klasse und auf den Klassenlader selbst den Weg des Dodos gehen müssen.
Eine mögliche Lösung für Ihr Problem besteht darin, für jede JAR-Datei einen Classloader und für jeden AppServer einen Classloader zu haben, der das tatsächliche Laden von Klassen an bestimmte Jar-Klassenlader delegiert. Auf diese Weise können Sie für jeden App-Server auf verschiedene Versionen der JAR-Datei verweisen.
Dies ist jedoch nicht trivial. Die OSGi-Plattform versucht genau dies zu tun, da jedes Bundle einen anderen Klassenladeprogramm hat und Abhängigkeiten von der Plattform aufgelöst werden. Vielleicht wäre eine gute Lösung, einen Blick darauf zu werfen.
Wenn Sie OSGI nicht verwenden möchten, besteht eine mögliche Implementierung darin, für jede JAR-Datei eine Instanz der JarClassloader- Klasse zu verwenden.
Erstellen Sie eine neue MultiClassloader-Klasse, die Classloader erweitert. Diese Klasse verfügt intern über ein Array (oder eine Liste) von JarClassloadern und durchläuft in der defineClass () -Methode alle internen Klassenloader, bis eine Definition gefunden wird oder eine NoClassDefFoundException ausgelöst wird. Es können verschiedene Zugriffsmethoden bereitgestellt werden, um der Klasse neue JarClassloader hinzuzufügen. Es gibt mehrere mögliche Implementierungen für einen MultiClassLoader im Internet, sodass Sie möglicherweise nicht einmal Ihre eigenen schreiben müssen.
Wenn Sie für jede Verbindung zum Server einen MultiClassloader instanziieren, ist es grundsätzlich möglich, dass jeder Server eine andere Version derselben Klasse verwendet.
Ich habe die MultiClassloader-Idee in einem Projekt verwendet, in dem Klassen, die benutzerdefinierte Skripte enthielten, aus dem Speicher geladen und entladen werden mussten, und es funktionierte recht gut.