Java: no security manager: RMI class loader disabled
Hallo ich habe eine RMI-Anwendung und nun versuche ich berufen einige Methoden, die auf dem server von meinem client. Ich habe folgenden code:
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();
}
}
server korrekt geladen, aber wenn ich versuche zu nennen server.registerOHLCProvider(provider);
bekomme ich diese Fehler:
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
Ich habe meine policy-Datei als VM-argument hier ist, wie es aussieht:
grant {
permission java.security.AllPermission;
}
Es sagt immer etwas über Behinderte zum laden von Klassen, also denke ich, problem ist irgendwo dort draußen ...
Danke!
- Wenn Sie das einbetten dieser Aufruf
System.getProperty("java.security.policy");
vor der Einstellung der Sicherheits-manager, was gibt es zurück? Irgendwie, ich denken Sie sollten die Sicherheits-policy-Eigenschaft im code, obwohl Sie ihn als ein command line argument. - Es richtig druckt Pfad der policy-Datei. /home/miso/workspace/IndikatoryClient/Sicherheit.Politik
Du musst angemeldet sein, um einen Kommentar abzugeben.
Remote-Klasse laden, kann schwierig sein.
Den original-post enthält keine Informationen über die code-Basis. Kann es sein, dass der client-security-Konfiguration ist korrekt, aber es hat keinen Zugriff auf die remote-code. Die Klassen geladen werden, die direkt aus der "code-Basis" durch den Kunden. Sie sind nicht präsentiert dem Kunden durch den service über die RMI Verbindung. Der service lediglich mit Verweis auf eine externe Quelle für den Unterricht.
Sollte der server geben Sie die system-Eigenschaft
java.rmi.server.codebase
. Der Wert muss eine URL zugänglich ist, an den client,, aus denen die notwendigen Klassen geladen werden können. Wenn dies einfile:
URL, dem Datei-system zugänglich sein muss der client.Werden und Umgekehrt: Wenn der server sollte in der Lage sein, um Klassen zu laden, die vom client (wie hier), muss der AUFTRAGGEBER festlegen, die code-Basis-Eigenschaft auf eine URL, die im Internet zu dem server.
Jedes mal, wenn Sie eine Methode aufzurufen, die auf einem RMI dynamic proxy, der
MarshalInputStream
(die sichObjectInputStream
überschreibenresolveClass
undresolveProxyClass
) die DelegiertenLoaderHandler
schauen Sie sich in 3 Plätze für dieClassLoader
zu verwenden:latestUserDefinedLoader()
: es wandert auf den Stapel, auf der Suche nach der ersten Methode auf dem stack, die nicht Teil des JRE).contextClassLoader
des Anrufersjava.rmi.server.useCodebaseOnly=false
, dann die codebase-ClassLoader verwendet URLs in der remotejava.rmi.server.codebase
. Beachten Sie, dass die Standardwert useCodebaseOnly geändert in JDK 7u21, so dass remote-Code-Basis nicht mehr verwendet, es sei denn, Sie ändern es!java.rmi.server.codebase
.Also es gibt ein paar mögliche Gründe, dass Sie eine
ClassNotFoundException
beim Aufruf einer Remote-Methode:-Djava.rmi.server.useCodebaseOnly=true
passend zum vorherigen Verhalten, oder legen Sie-Djava.rmi.server.codebase
um eine durch Leerzeichen getrennte Liste von URLs, auf die sowohl die lokalen und die remote-Seiten. Und stellen Sie sicher, dass computer können Sie den Zugriff auf diese URLs.Thread.setContextClassLoader(ClassLoader)
so, die RMI verwenden, dass ClassLoader. (Das war mein problem: ich hatte eineSwingWorker
dass war geplant auf einen worker-thread, der erstellt wurde, bevor die contextClassLoader auf dem EventDispatchThread). Zum Beispiel, A und C gehören zu Ihren benutzerdefinierten ClassLoader aber B gehört zu den übergeordneten ClassLoader, dann, wenn Sie anrufen ein.getB().getC(), die getB () - Aufruf wird die Verwendung der benutzerdefinierten classloader, aber die getC () - Aufruf wird scheitern, Sie zu finden C in der latestUserDefinedClassLoader und müssen wieder fallen zu contextClassLoader.All dies ist ein warnendes Beispiel auf schlechte API-design von ObjectInputStream. ObjectInputStream benötigt haben sollten, Sie zu übergeben, die ein Klassenladeprogramm parameter, nicht versuchen, einen zu finden, willkürlich mit latestUserDefinedLoader, contextClassLoader, und codebase.
-Djava.rmi.server.useCodebaseOnly=true
passend zum vorherigen Verhalten" gelesen werden müssen-Djava.rmi.server.useCodebaseOnly=false
. Verweis.Müssen Sie die security manager auf der server-Seite, nicht nur auf der client-Seite.
Ohne das der server die RMI-engine verweigert das laden von Klassen aus dem client, da es nicht garantieren kann, dass diese nicht tun, böse Dinge auf dem server.
Tun, müssen Sie die RMI-Klasse laden überhaupt? Konnte nicht die server haben bereits die Klassen, die der client versucht, zu senden?
new SecurityManager()
oder Ihre benutzerdefinierten Sicherheits-manager, wie die RMISecurityManager tut hier nichts besonderes). Ich bin mir nicht sicher, ob Ihr AllPermission ist wirklich das, was Sie wollen, auf die Produktion von Systemen, obwohl.Weiß ich, warum es passiert.
zum Beispiel Sie starten Sie den server in das Projekt Ein,
aber Sie verwenden den Client in das Projekt B zu verlangen, diesem server,dieser ist falsch.
So sollte man die server-und client im selben Projekt.