Oryginalna odpowiedź Adama Batkina doprowadzi Cię do rozwiązania, ale jeśli ponownie wdrożysz aplikację internetową (bez ponownego uruchamiania kontenera internetowego), powinieneś napotkać następujący błąd:
java.lang.UnsatisfiedLinkError: Native Library "foo" already loaded in another classloader
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1715)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1646)
at java.lang.Runtime.load0(Runtime.java:787)
at java.lang.System.load(System.java:1022)
Dzieje się tak, ponieważ ClassLoader, który pierwotnie załadował bibliotekę DLL, nadal odwołuje się do tej biblioteki DLL. Jednak Twoja aplikacja internetowa działa teraz z nowym ClassLoaderem, a ponieważ ta sama JVM jest uruchomiona, a JVM nie zezwala na 2 odwołania do tej samej biblioteki DLL, nie możesz jej ponownie załadować . Dlatego Twoja aplikacja internetowa nie może uzyskać dostępu do istniejącej biblioteki DLL i nie może załadować nowej. Więc ... utknęłaś.
Dokumentacja Tomcat ClassLoader przedstawia, dlaczego ponownie załadowana aplikacja internetowa działa w nowej, izolowanej aplikacji ClassLoader i jak można obejść to ograniczenie (na bardzo wysokim poziomie).
Rozwiązaniem jest niewielkie rozszerzenie rozwiązania Adama Batkina:
package awesome;
public class Foo {
static {
System.loadLibrary('foo');
}
public static void main(String[] args) {
}
}
Następnie umieść jar zawierający TYLKO tę skompilowaną klasę w folderze TOMCAT_HOME / lib.
Teraz w aplikacji internetowej wystarczy zmusić Tomcat do odwoływania się do tej klasy, co można zrobić tak prosto:
Class.forName("awesome.Foo");
Teraz Twoja biblioteka DLL powinna zostać załadowana do wspólnego modułu ładującego klasy i można do niej odwoływać się z aplikacji internetowej nawet po ponownym wdrożeniu.
Ma sens?
Roboczą kopię referencyjną można znaleźć w google code, static-dll-bootstrapper .