Java: no security manager: RMI class loader disabled

Witam mam aplikację RMI i teraz próbuję wywołać kilka metod na serwerze od mojego klienta. Mam następujący kod:

public static void main(final String[] args) {
    try {
        //Setting the security manager

        System.setSecurityManager(new RMISecurityManager());
        IndicatorsService server = (IndicatorsService) Naming
                .lookup("rmi://localhost/" + IndicatorsService.SERVICE_NAME);
        DataProvider provider = new OHLCProvider(server);
        server.registerOHLCProvider(provider);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (RemoteException e) {
        e.printStackTrace();
    } catch (NotBoundException e) {
        e.printStackTrace();
    }
}

Serwer jest poprawnie załadowany, ale kiedy próbuję wywołać server.registerOHLCProvider(provider); dostaję te błędy:

     java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:336)
    at sun.rmi.transport.Transport$1.run(Transport.java:159)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
    at sk.fri.statistics.service.impl.IndicatorsServiceImpl_Stub.registerOHLCProvider(Unknown Source)
    at sk.fri.statistics.service.Client.main(Client.java:61)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:296)
    at sun.rmi.transport.Transport$1.run(Transport.java:159)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: sk.xorty.client.providers.OHLCProvider (no security manager: RMI class loader disabled)
    at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:375)
    at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
    at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
    at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
    at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:290)
    ... 9 more

Dodałem mój plik policy jako argument VM, oto jak to wygląda:

grant {
    permission java.security.AllPermission;
}

Ciągle mówi coś o wyłączonych klasach, więc chyba problem gdzieś tam jest ... Dzięki!

Author: Mark, 2011-06-12

6 answers

Zdalne Ładowanie klas może być trudne.

Oryginalny post nie zawiera żadnych informacji o bazie kodu. Być może konfiguracja zabezpieczeń klienta jest poprawna, ale nie ma on dostępu do zdalnego kodu. Klasy są ładowane bezpośrednio z" bazy kodu " przez Klienta. Nie są one prezentowane Klientowi przez serwis za pośrednictwem połączenia RMI. Serwis odwołuje się jedynie do zewnętrznego źródła dla klas.

Serwer powinien określać właściwość systemu java.rmi.server.codebase. Wartość musi być adresem URL dostępnym dla Klienta, , z którego można załadować potrzebne klasy. Jeśli jest to adres URL file:, system plików musi być dostępny dla klienta.

I odwrotnie: jeśli serwer ma być w stanie załadować klasy z Klienta (jak tutaj), klient musi ustawić właściwość code base na adres URL, który jest dostępny dla serwera.

 28
Author: erickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-14 19:58:33

Za każdym razem, gdy wywołujesz metodę na dynamicznym proxy RMI,MarshalInputStream ( który rozszerza ObjectInputStream aby zastąpić resolveClass i resolveProxyClass) delegatów do LoaderHandler aby wyszukać w 3 miejscach ClassLoader do użycia:

  1. ClassLoader serwera proxy, który jest wywoływany (technicznie używa hakera o nazwie latestUserDefinedLoader(): wchodzi po stosie, szukając pierwszej metody na stosie, która nie jest częścią JRE).
  2. Thread-local contextClassLoader rozmówcy
  3. Codebase ClassLoader jeśli SecurityManager jest włączony
    1. Jeśli właściwość systemowa java.rmi.server.useCodebaseOnly=false, to ClassLoader bazy kodowej używa adresów URL w zdalnym java.rmi.server.codebase. Zauważ, że domyślna wartość useCodebaseOnly została zmieniona w JDK 7u21 tak, że zdalna baza kodowa nie jest już używana, chyba że ją zmienisz!
    2. W Przeciwnym Razie, ClassLoader bazy kodowej używa adresów URL w lokalnym java.rmi.server.codebase.

Jest więc kilka możliwych powodów, dla których otrzymałbyś ClassNotFoundException podczas wywoływania zdalnej metody:

  • jeśli stos zawiera "no security manager: RMI class loader disabled", upewnij się, że ustawiłeś SecurityManager tak jak to opisali inni, jeśli potrzebujesz zdalnego ładowania klas dla obu stron, aby uzyskać wszystkie zdalne interfejsy i klasy serializowalne.
  • Jeśli używasz Zdalnego Ładowania klasy i przestało działać po aktualizacji do JRE 7u21, Ustaw -Djava.rmi.server.useCodebaseOnly=true, aby dopasować poprzednie zachowanie, lub ustaw -Djava.rmi.server.codebase na oddzieloną spacjami listę adresów URL na zarówno po stronie lokalnej, jak i odległej. I upewnij się, że komputer ma dostęp do tych adresów URL.
  • Jeśli używasz lokalnie niestandardowego Classloadera, którego rodzic classloader definiuje niektóre zdalne interfejsy, upewnij się, że wywołujesz Thread.setContextClassLoader(ClassLoader), aby RMI użyło tego Classloadera. (To był mój problem: miałem SwingWorker, który został zaplanowany w wątku roboczym, który został utworzony przed ustawieniem contextClassLoader na EventDispatchThread). Na przykład A I C należą do twojego zwyczaju ClassLoader ale B należy do nadrzędnego Classloadera, wtedy gdy wywołujesz. getB ().getC(), getb() użyje niestandardowego classloadera, ale getC() nie znajdzie C w najnowszym userdefinedclassloader i będzie musiał wrócić do contextClassLoader.

Wszystko to jest przestrogą na temat słabego projektowania API ObjectInputStream. ObjectInputStream powinien wymagać od Ciebie podania parametru ClassLoader, a nie próbowania znalezienia go za pomocą latestUserDefinedLoader, contextClassLoader i codebase.

 7
Author: yonran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-29 18:29:12

[7]}chcę dodać coś, co może być pomocne dla niektórych osób, zwłaszcza początkujących. Przyszedłem tutaj i szukałem rozwiązania dla powyższego błędu, ale będąc początkującym, nie wiedziałem, jak korzystać z zasad bezpieczeństwa i określić " java.rmi.serwer.codebase " atrybut. Najprostszym sposobem naprawienia tego błędu jest upewnienie się, że klasy obiektów wysyłanych przez RMI znajdują się w tej samej ścieżce pakietów.. W ten sposób obie aplikacje mają klasę w tej samej lokalizacji względem swojej główny folder i błąd zostanie rozwiązany.

Przykład: Jeśli chcesz wysłać obiekt typu MedicationDTO (który można serializować) z serwera do klienta, upewnij się, że znajduje się on w tej samej ścieżce pakietów. W moim przypadku w aplikacji serwerowej obiekt znajdował się w com.example.springdemo.dto, a w aplikacji klienckiej w com.example.springdemo.service.dto.. Problem polegaĺ 'na tym, Ĺźe uĹźywajÄ ... C IntelliJ, poniewaĹź pakiet service nie miaĹ' nic w sobie, ale inny pakiet, ich nazwa byĹ 'a konkatenowana (service.dto) i nie widziaĹ' em, Ĺźe Ĺ "cieĺźka nie byĹ' a taka sama. Więc zrób upewnij się, że Twoje klasy mają tę samą ścieżkę pakietów. (Rozwiązanie dla mojego przypadku: MedicationDTO klasa musi być w obu aplikacjach w pakiecie: com.example.springdemo.dto.

Wiem, że to nie jest najlepsze rozwiązanie, to tylko "mała sztuczka" , ale byłbym niezmiernie szczęśliwy, mogąc znaleźć takie rozwiązanie, ponieważ zaoszczędziło mi to wiele straconego czasu na rozwiązanie problemu.

Mam nadzieję, że będzie to pomocne dla tych, którzy chcą szybkiej naprawy tego błędu, ponieważ myślę, że nauka korzystania z menedżerów bezpieczeństwa i w tym codebase może być trochę trudne i zajmie trochę czasu.

 7
Author: Popovici Marius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-17 10:32:16

Potrzebujesz security manager Po stronie serwera, nie tylko po stronie klienta.

Bez tego, silnik RMI serwera odmawia załadowania klas od klienta, ponieważ nie może zagwarantować, że te nie zrobią złych rzeczy na serwerze.

Czy w ogóle potrzebujesz ładowania klasy RMI? Czy serwer nie może mieć już klas, które klient próbuje wysłać?

 4
Author: Paŭlo Ebermann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-18 20:42:38

Wiem, że moja sprawa jest wyjątkowo wyjątkowa, ale może pomaga innym. Miałem przypadek, że na jednym serwerze było wiele aplikacji dzielących ten sam rejestr z różnymi ścieżkami oczywiście. Wszędzie tam, gdzie ten rejestr jest tworzony (zwykle z pierwszej aplikacji), musi być określona pełna ścieżka klas wszystkich późniejszych aplikacji w tej pierwszej aplikacji. Podsumowując:

  1. Upewnij się, że polityka jest zapewniona
  2. Upewnij się, że classpath jest pełna określona dla wszystkich aplikacji, klientów i Serwer
 0
Author: Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-02-10 09:37:18

Wiem, dlaczego tak się dzieje. na przykład uruchamiasz serwer w projekcie A, ale używasz klienta w projekcie B, aby zażądać tego serwera,to jest złe. Więc powinieneś umieścić serwer i klienta w tym samym projekcie.

 -4
Author: user3556213,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-21 11:09:58