RMI 注册表权限被拒绝



我正在尝试开始使用java RMI,但是当我的组件尝试绑定(甚至连接)到rmiregistry时,我不断遇到错误。每当我尝试将任何东西绑定到rmiregisrty时,我都会得到一个 java.rmi.ConnectIOException。老实说,我不知道我需要做些什么来解决这个问题。

法典

服务器

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) throws Exception {

HelloClass Obj = new HelloClass();
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", Obj);
System.out.println("Server is live");
}
}

客户

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {
public static void main(String[] args) throws Exception{

Registry registry = LocateRegistry.getRegistry();
Hello hello = (Hello) registry.lookup("Hello");
String n = hello.Hello();
System.out.println(n);
}
}

你好(接口)

import java.rmi.*;
public interface Hello extends Remote {
public String Hello() throws RemoteException;
}

你好班

import java.rmi.server.UnicastRemoteObject;
public class HelloClass extends UnicastRemoteObject implements Hello  {
public HelloClass() throws Exception{
super();
}
public String Hello(){
return "Hello world!";
}
}

错误

"C:Program FilesJavajdk1.8.0_144binjava.exe" "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.4libidea_rt.jar=57417:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.4bin" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.8.0_144jrelibcharsets.jar;C:Program FilesJavajdk1.8.0_144jrelibdeploy.jar;C:Program FilesJavajdk1.8.0_144jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.8.0_144jrelibextcldrdata.jar;C:Program FilesJavajdk1.8.0_144jrelibextdnsns.jar;C:Program FilesJavajdk1.8.0_144jrelibextjaccess.jar;C:Program FilesJavajdk1.8.0_144jrelibextjfxrt.jar;C:Program FilesJavajdk1.8.0_144jrelibextlocaledata.jar;C:Program FilesJavajdk1.8.0_144jrelibextnashorn.jar;C:Program FilesJavajdk1.8.0_144jrelibextsunec.jar;C:Program FilesJavajdk1.8.0_144jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.8.0_144jrelibextsunmscapi.jar;C:Program FilesJavajdk1.8.0_144jrelibextsunpkcs11.jar;C:Program FilesJavajdk1.8.0_144jrelibextzipfs.jar;C:Program FilesJavajdk1.8.0_144jrelibjavaws.jar;C:Program FilesJavajdk1.8.0_144jrelibjce.jar;C:Program FilesJavajdk1.8.0_144jrelibjfr.jar;C:Program FilesJavajdk1.8.0_144jrelibjfxswt.jar;C:Program FilesJavajdk1.8.0_144jrelibjsse.jar;C:Program FilesJavajdk1.8.0_144jrelibmanagement-agent.jar;C:Program FilesJavajdk1.8.0_144jrelibplugin.jar;C:Program FilesJavajdk1.8.0_144jrelibresources.jar;C:Program FilesJavajdk1.8.0_144jrelibrt.jar;C:UsersRomanDesktopRMI3outproductionRMI3" Server
Exception in thread "main" java.rmi.ConnectIOException: Exception creating connection to: 192.168.2.21; nested exception is: 
**"C:Program FilesJavajdk1.8.0_144binjava.exe" "-javaagent:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.4libidea_rt.jar=57417:C:Program FilesJetBrainsIntelliJ IDEA 2019.3.4bin" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.8.0_144jrelibcharsets.jar;C:Program FilesJavajdk1.8.0_144jrelibdeploy.jar;C:Program FilesJavajdk1.8.0_144jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.8.0_144jrelibextcldrdata.jar;C:Program FilesJavajdk1.8.0_144jrelibextdnsns.jar;C:Program FilesJavajdk1.8.0_144jrelibextjaccess.jar;C:Program FilesJavajdk1.8.0_144jrelibextjfxrt.jar;C:Program FilesJavajdk1.8.0_144jrelibextlocaledata.jar;C:Program FilesJavajdk1.8.0_144jrelibextnashorn.jar;C:Program FilesJavajdk1.8.0_144jrelibextsunec.jar;C:Program FilesJavajdk1.8.0_144jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.8.0_144jrelibextsunmscapi.jar;C:Program FilesJavajdk1.8.0_144jrelibextsunpkcs11.jar;C:Program FilesJavajdk1.8.0_144jrelibextzipfs.jar;C:Program FilesJavajdk1.8.0_144jrelibjavaws.jar;C:Program FilesJavajdk1.8.0_144jrelibjce.jar;C:Program FilesJavajdk1.8.0_144jrelibjfr.jar;C:Program FilesJavajdk1.8.0_144jrelibjfxswt.jar;C:Program FilesJavajdk1.8.0_144jrelibjsse.jar;C:Program FilesJavajdk1.8.0_144jrelibmanagement-agent.jar;C:Program FilesJavajdk1.8.0_144jrelibplugin.jar;C:Program FilesJavajdk1.8.0_144jrelibresources.jar;C:Program FilesJavajdk1.8.0_144jrelibrt.jar;C:UsersRomanDesktopRMI3outproductionRMI3" Server
Exception in thread "main" java.rmi.ConnectIOException: Exception creating connection to: 192.168.2.21; nested exception is: 
java.net.SocketException: Permission denied: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:631)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:338)
at sun.rmi.registry.RegistryImpl_Stub.bind(RegistryImpl_Stub.java:60)
at Server.main(Server.java:15)
Caused by: java.net.SocketException: Permission denied: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 5 more
**
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:631)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:338)
at sun.rmi.registry.RegistryImpl_Stub.bind(RegistryImpl_Stub.java:60)
at Server.main(Server.java:15)
Caused by: java.net.SocketException: Permission denied: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 5 more

在服务器类中,通过调用LocateRegistry.getRegistry()方法来检索远程对象注册表引用。

由于主机名和端口未传递,因此内部主机名将使用java.net.InetAddress.getLocalHost().getHostAddress()API 派生。

根据错误消息,主机名派生为 192.168.2.21,但在该 IP 上尝试在端口 1099 中创建套接字时出现权限被拒绝错误。

从中运行服务器类的主机,

该节点是否IP_ADDRESS 192.168.2.21 ?

您可以使用

ipconfig /all

您可以使用java.net.InetAddress.getLocalHost().getHostAddress()API 进行检查。

我认为更好的是您可以尝试将主机名和端口传递给LocateRegistry.getRegistry("127.0.0.1",1099)方法。更改位于服务器和客户端代码中。

服务器.java

package rmi.learning;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) throws Exception {
try {
HelloClass Obj = new HelloClass();
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099);
System.out.println("registry=" + registry);
registry.bind("Hello", Obj);
System.out.println("Server is live");
} catch (Exception e) {
e.printStackTrace();
}
}
}

客户端.java

package rmi.learning;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {
public static void main(String[] args) throws Exception{

Registry registry = LocateRegistry.getRegistry("127.0.0.1",1099);
Hello hello = (Hello) registry.lookup("Hello");
String n = hello.Hello();
System.out.println(n);
}
}

我已将所有类放在 rmi.learning 包中。

你好.java

package rmi.learning;
import java.rmi.*;
public interface Hello extends Remote {
public String Hello() throws RemoteException;
}

你好班级.java

package rmi.learning;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class HelloClass extends UnicastRemoteObject implements Hello {
protected HelloClass() throws RemoteException {
super();
}
public String Hello() {
return "Hello world!";
}
}

启动 RMI 注册表服务

start  d:Javajdk1.8.0_261binrmiregistry

从命令提示符: 执行服务器

cd d:workspace_europaStackOverflowbin
start /B  D:Javajdk1.8.0_261binjava.exe -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server

输出:

registry=RegistryImpl_Stub[UnicastRef [liveRef: [endpoint:[127.0.0.1:1099](remote),objID:[0:0:0, 0]]]]
Server is live

从命令提示符: 执行客户端

D:Javajdk1.8.0_261binjava.exe -classpath .  rmi.learning.Client

输出:

Hello world!

更多调查:

我试图重现这个问题,我通过路由器连接到互联网。一旦我连接到wifi,那么我的路由器就会分配IP地址192.168.0.102。java.net.InetAddress.getLocalHost().getHostAddress()API 返回 IP 地址为 192.168.0.102

Wireless LAN adapter Wi-Fi:
Connection-specific DNS Suffix  . :
Link-local IPv6 Address . . . . . : xxxx::xxxx:xxxx:xxxx:xxxx%18
IPv4 Address. . . . . . . . . . . : 192.168.0.102
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.0.1

如果我尝试将 rmi 服务绑定到端口 192.168.0.102 中的 1099,那么它工作正常。

但是,如果我连接到VPN,则会为我的主机分配一个新IP。连接到VPN时,IP 192.168.0.102不再可解析,我的机器IP_ADDRESS正在更改。这次如果我尝试将 rmi 服务绑定到 IP 192.168.0.102,则会收到错误java.net.SocketException: Permission denied: connect.

因此,如果IP地址不再适用于当前节点,则错误即将到来。

在我看到的许多地方,人们建议使用 -Djava.net.preferIPv4Stack=true also.运行服务器时.class您可以尝试类似的

start /B  D:Javajdk1.8.0_261binjava.exe -Djava.net.preferIPv4Stack=true -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server

甚至有些人说要禁用系统上运行的任何防病毒软件,您也可以检查这种可能性。

最新更新