2017-02-03 62 views
7

Zasadniczo mam Javę system, który uruchamia szereg skryptów "plugin" używających Javascript przez Rhino lub Nashorn, w zależności od tego, co użytkownik JRE zainstalował.Dodawanie i usuwanie plików i klas Jar z poziomu JavaScript (Rhino/Nashorn)

Mam również system w środowisku Java, który pozwala na podłączenie dodatkowych plików JAR w czasie wykonywania.

Wszystko w porządku i dandy. Jednak natknąłem się na sytuację, w której chcę coś nieco innego: chcę załadować plik .JAR do klasy ClassPath z wewnątrz instancji silnika Rhino/Nashorn, więc klasy są dostępne dla tej instancji (i tylko ta instancja), a następnie usunąć je, gdy silnik zakończy pracę.

Wiem, że mogę łatwo wywołać moją istniejącą procedurę Java, aby załadować URL pliku .JAR z JavaScript, jednak klasy są wtedy zainstalowane na stałe i nie mogę się ich pozbyć.

Problem polega głównie na tym, że użytkownik może mieć wiele wtyczek z różnymi wersjami tego samego pliku .JAR (jest dostarczany przez inną firmę i używany do wielu różnych wtyczek na różne sposoby) i potrzebuję wtyczek aby móc załadować właściwy, a następnie porzucić go.

Moja istniejący ładowarka URL:

public static void addURL(URL u) { 
    final Class[] parameters = new Class[]{URL.class}; 
    URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); 
    Class sysclass = URLClassLoader.class; 

    try { 
     Method method = sysclass.getDeclaredMethod("addURL", parameters); 
     method.setAccessible(true); 
     method.invoke(sysloader, new Object[]{u}); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
} 

Teraz nie mamy dużo pojęcia jak to działa - nie jestem programista Java zasilania (zrobić C/C++ głównie). Wiem, że nie można "wyładować" URL z URLClassLoader, więc nie o to pytam. Najlepiej byłoby, gdyby był sposób, w jaki mogłem dodać plik .JAR do "tymczasowego" URLClassLoadera, który następnie wyłomiłbym na końcu egzekucji. Lub w jakiś sposób mogę po prostu załadować klasy bezpośrednio do silnika skryptu, a nie do głównej klasy Java ClassPath.

Jeśli jest to coś, co mógłbym po prostu wywołać bezpośrednio z JavaScript, byłoby wspaniale, ale nie mam nic przeciwko implementacji niektórych metod Java, jeśli to konieczne, lub nawet rozszerzeniu silnika skryptów w jakiś sposób.

Odpowiedz

5

Aby wyizolować klasy specyficzne dla wtyczki, konieczne może być utworzenie oddzielnej (niestandardowej) instancji modułu ładującego klasy i przekazanie jej do silnika skryptu Java. Każda klasa załadowana przez konkretny program ładujący klasy będzie widoczna tylko dla określonego mechanizmu skryptu java.

Znalazłem this answer, które opisują program ładujący klasy w kontekście ScriptEngine.

Mam nadzieję, że pomoże to w postępie we właściwym kierunku.