Xor*_*rty 26 java networking remoting rmi securitymanager
嗨,我有RMI应用程序,现在我尝试从我的客户端调用服务器上的一些方法.我有以下代码:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
服务器已正确加载,但当我尝试调用时,server.registerOHLCProvider(provider);
我收到以下错误:
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
Run Code Online (Sandbox Code Playgroud)
我已将我的策略文件添加为VM参数,以下是它的样子:
grant {
permission java.security.AllPermission;
}
Run Code Online (Sandbox Code Playgroud)
它一直在说关于禁用类加载的东西,所以我猜问题就在那里...谢谢!
eri*_*son 25
远程类加载可能很棘手.
原始帖子不包含有关代码库的任何信息.可能是客户端的安全配置正确,但它无法访问远程代码.这些类由客户端直接从"代码库"加载.它们不是由服务通过RMI连接呈现给客户端的.该服务仅引用类的外部源.
服务器应指定系统属性java.rmi.server.codebase
.该值必须是客户端可以访问的URL ,可以从中加载必需的类.如果这是file:
URL,则客户端必须可以访问文件系统.
反过来说:如果服务器应该能够从客户端加载类(如此处),则客户端必须将代码库属性设置为服务器可访问的URL.
每次在RMI动态代理上调用方法时,MarshalInputStream
(扩展ObjectInputStream
为覆盖resolveClass
和resolveProxyClass
)委托LoaderHandler
以查找3个位置以供ClassLoader
使用:
latestUserDefinedLoader()
:它向上移动堆栈,寻找堆栈中不属于JRE的第一个方法).contextClassLoader
调用者的线程本地java.rmi.server.useCodebaseOnly=false
,则代码库ClassLoader使用远程 URL java.rmi.server.codebase
.请注意,在JDK 7u21中更改了useCodebaseOnly的默认值,因此除非您更改远程代码库,否则不再使用远程代码库!java.rmi.server.codebase
.因此,ClassNotFoundException
在调用Remote方法时,您会得到一些可能的原因:
-Djava.rmi.server.useCodebaseOnly=true
为匹配先前的行为,或设置-Djava.rmi.server.codebase
为本地和远程端的空格分隔的URL列表.并确保计算机可以访问这些URL.Thread.setContextClassLoader(ClassLoader)
以便RMI将使用该ClassLoader.(这是我的问题:我SwingWorker
碰巧安排到在EventDispatchThread上设置contextClassLoader之前创建的工作线程).例如,A和C属于您的自定义ClassLoader,但B属于父ClassLoader,那么当您调用a.getB().getC()时,getB()调用将使用自定义类加载器,但getC()调用将无法在latestUserDefinedClassLoader中找到C并且必须回退到contextClassLoader.所有这些都是对ObjectInputStream API设计不佳的警示.ObjectInputStream应该要求您传递ClassLoader参数,而不是尝试使用latestUserDefinedLoader,contextClassLoader和codebase来随意查找.
小智 7
我想添加一些可能对某些人有用的东西,尤其是初学者。我来到这里并搜索上述错误的解决方案,但作为初学者,我不知道如何使用安全策略并指定“java.rmi.server.codebase”属性。修复该错误的最简单方法是确保要通过 RMI 发送的对象的类位于包的同一路径中。错误将解决。
示例:如果要将类型MedicationDTO
(可序列化)的对象从服务器发送到客户端,请确保它位于相同的包路径中。在我的情况下,在服务器应用程序,对象是com.example.springdemo.dto
在客户端应用程序,它是在com.example.springdemo.service.dto
..问题是,使用的IntelliJ,因为service
包在里面什么都没有,但另一包,他们的名字被级联(service.dto
),我看不出路径不一样。因此,请确保您的类具有相同的包路径。(我的情况的解决方案:MedicationDTO
类必须在包中的两个应用程序中:com.example.springdemo.dto
.
我知道这不是最好的解决方案,它只是一个“小技巧”,但我会非常高兴找到这个解决方案,因为它让我免于浪费大量时间来解决问题。
我希望这对那些想要快速修复该错误的人有所帮助,因为我认为学习使用安全管理器和包含代码库可能有点棘手,需要时间。