java.rmi.AccessException:不允许使用Registry.rebind;origin/10.0.0.71是非本地主机
我有一个使用RMI的简单客户机/服务器计算器应用程序。服务器和客户端位于不同的linux机器中。客户端ip为10.0.0.71,服务器ip为10.0.1.100 这是远程接口:java.rmi.AccessException:不允许使用Registry.rebind;origin/10.0.0.71是非本地主机,java,rmi,remote-access,remote-server,Java,Rmi,Remote Access,Remote Server,我有一个使用RMI的简单客户机/服务器计算器应用程序。服务器和客户端位于不同的linux机器中。客户端ip为10.0.0.71,服务器ip为10.0.1.100 这是远程接口: package com.simplecalc.commons; import java.rmi.Remote; import java.rmi.RemoteException; public interface Calculator extends Remote { public float add(floa
package com.simplecalc.commons;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Calculator extends Remote {
public float add(float a, float b) throws RemoteException;
}
package com.simplecalc.server;
import java.rmi.RemoteException;
import com.simplecalc.commons.Calculator;
public class CalculatorImpl implements Calculator {
@Override
public float add(float a, float b) throws RemoteException {
float result = a + b;
System.out.println("$ (" + a + " + " + b + ") = " + result);
return result;
}
}
这是实现远程接口的服务器端代码:
package com.simplecalc.commons;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Calculator extends Remote {
public float add(float a, float b) throws RemoteException;
}
package com.simplecalc.server;
import java.rmi.RemoteException;
import com.simplecalc.commons.Calculator;
public class CalculatorImpl implements Calculator {
@Override
public float add(float a, float b) throws RemoteException {
float result = a + b;
System.out.println("$ (" + a + " + " + b + ") = " + result);
return result;
}
}
这是运行应用程序的服务器端代码:
package com.simplecalc.server;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import com.simplecalc.commons.Calculator;
public class Server {
private static void setPolicy() {
System.setProperty("java.security.policy", "file:///calculator.policy");
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
}
public static void main(String[] args) throws RemoteException {
setPolicy();
int port = 1099;
Calculator engine = new CalculatorImpl();
Calculator stub = (Calculator) UnicastRemoteObject.exportObject(engine, 0);
Registry registry = LocateRegistry.getRegistry(port);
System.out.println("Registering calculator object ...");
registry.rebind(Calculator.class.getSimpleName(), stub);
}
}
最后,这是调用计算器的客户端:
package com.simplecalc.client;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import com.simplecalc.commons.Calculator;
public class CalculatorClient {
private static void setPolicy() {
System.setProperty("java.security.policy", "file:///calculator.policy");
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
}
public static void main(String[] args) throws RemoteException, NotBoundException {
setPolicy();
int port = 1099;
String server="10.0.1.100";
Registry registry = LocateRegistry.getRegistry(server, port);
Calculator calculator = (Calculator) registry.lookup(Calculator.class.getSimpleName());
registry.rebind(server, calculator);
float result = calculator.add(10F, 5F);
System.out.println("Result: " + result);
}
}
这是计算器.policy
文件:
grant {
permission java.security.AllPermission;
permission java.net.SocketPermission "localhost:1099", "connect, resolve";
permission java.net.SocketPermission "127.0.0.1:1099", "connect, resolve";
permission java.net.SocketPermission "10.0.0.71:1099", "connect, resolve";
permission java.net.SocketPermission "localhost:80", "connect, resolve";
};
grant {
permission java.security.AllPermission;
};
我编译了服务器代码并成功启动了RMI注册表,如下所示:
cd server_classes_directory
rmiregistry 1099 &
然后我成功地运行了类com.simplecalc.server.server
当我运行类com.simplecalc.client.CalculatorClient
时,我得到一个异常:
Exception in thread "main" java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.AccessException: Registry.rebind disallowed; origin /10.0.0.71 is non-local host
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:389)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:835)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer( StreamRemoteCall.java:283)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:260)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:375)
at sun.rmi.registry.RegistryImpl_Stub.rebind(RegistryImpl_Stub.java:155)
at com.simplecalc.client.CalculatorClient.main(CalculatorClient.java:27)
Caused by: java.rmi.AccessException: Registry.rebind disallowed; origin /10.0.0.71 is non-local host
at sun.rmi.registry.RegistryImpl.checkAccess(RegistryImpl.java:350)
at sun.rmi.registry.RegistryImpl_Skel.dispatch(RegistryImpl_Skel.java:128)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:468)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:300)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:835)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
有什么想法吗?正如错误所说,您不能绑定、重新绑定或取消绑定到远程注册表。您必须在同一台主机上运行。这是RMI的基本安全措施
但你的客户一开始不应该做绑定。这没有道理。它所要做的只是将刚刚查找到的服务器重新绑定到同一个注册表中。把它取下来。我终于发现了问题
SecurityManager
UnicastRemoteObject
package com.simplecalc.server;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import com.simplecalc.commons.Calculator;
public class CalculatorImpl extends UnicastRemoteObject implements Calculator {
@Override
public float add(float a, float b) throws RemoteException {
float result = a + b;
System.out.println("$ (" + a + " + " + b + ") = " + result);
return result;
}
}
这是新的服务器类:
package com.simplecalc.server;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import com.simplecalc.commons.Calculator;
public class Server {
public static void main(String[] args) throws RemoteException {
final int port = 1099;
final String serverIp = "10.0.1.100";
final String serviceName = Calculator.class.getSimpleName();
final String url = "rmi://" + serverIp + ":" + port + "/" + serviceName;
System.out.println("Registering calculator object ...");
CalculatorImpl engine = new CalculatorImpl();
Naming.rebind(url, engine);
System.out.println("Server listening on " + url);
}
}
这是新的客户端类:
package com.simplecalc.client;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import com.simplecalc.commons.Calculator;
public class CalculatorClient {
public static void main(String[] args) throws RemoteException, NotBoundException {
final int port = 1099;
final String serverIp = "10.0.1.100";
final String serviceName = Calculator.class.getSimpleName();
final String url = "rmi://" + serverIp + ":" + port + "/" + serviceName;
Calculator calculator = (Calculator) Naming.lookup(url);
float result = calculator.add(10F, 5F);
System.out.println("Result: " + result);
}
}
calculator.policy
文件:
grant {
permission java.security.AllPermission;
permission java.net.SocketPermission "localhost:1099", "connect, resolve";
permission java.net.SocketPermission "127.0.0.1:1099", "connect, resolve";
permission java.net.SocketPermission "10.0.0.71:1099", "connect, resolve";
permission java.net.SocketPermission "localhost:80", "connect, resolve";
};
grant {
permission java.security.AllPermission;
};
最后你找到了吗?(1) 你已经被告知了,这是你在这里唯一需要做的事情。(2) 在这里是正确的,但并非所有情况下都是如此,也不是导致此问题的原因。(3) 不正确:您可以手动导出它,如下所述。(4) 与此完全无关,因为您现在没有安全管理器EJP 14分钟前在某些情况下,例如容器化,您实际上希望从远程注册表绑定。请不要假设StackOverflow上的每个问题都是XY问题。