RMI Registry 权限被拒绝

huangapple go评论65阅读模式
英文:

RMI Registry permission denied

问题

我正在尝试开始使用Java RMI,但是当我的组件尝试绑定(甚至连接)到rmiregistry时,我一直遇到错误。每当我尝试将任何东西绑定到rmiregistry时,都会出现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("服务器已启动");
    }
}

客户端

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);
    }
}

Hello接口

import java.rmi.*;

public interface Hello extends Remote {

    public String Hello() throws RemoteException;

}

HelloClass

import java.rmi.server.UnicastRemoteObject;

public class HelloClass extends UnicastRemoteObject implements Hello  {

    public HelloClass() throws Exception{
        super();
    }

    public String Hello(){
        return "Hello world!";
    }

}

错误信息

Exception in thread "main" java.rmi.ConnectIOException: 在连接创建时出现异常:192.168.2.21;嵌套异常是: 
	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

以上是您提供的内容的翻译。如有需要,还请进一步指示。

英文:

I am trying to get started with java RMI but I keep running in to an error when my components try to bind (or even connect) to the rmiregistry. Whenever I try to bind anything to the rmiregisrty I get a java.rmi.ConnectIOException. I am honestly lost as to what I need to do to fix this.

code

Server

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(&quot;Hello&quot;, Obj);

        System.out.println(&quot;Server is live&quot;);
    }
}

Client

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(&quot;Hello&quot;);

        String n = hello.Hello();

        System.out.println(n);
    }
}

Hello (interface)

import java.rmi.*;

public interface Hello extends Remote {

    public String Hello() throws RemoteException;

}

HelloClass

import java.rmi.server.UnicastRemoteObject;

public class HelloClass extends UnicastRemoteObject implements Hello  {

    public HelloClass() throws Exception{
        super();
    }

    public String Hello(){
        return &quot;Hello world!&quot;;
    }

}

The error

&quot;C:\Program Files\Java\jdk1.8.0_144\bin\java.exe&quot; &quot;-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=57417:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin&quot; -Dfile.encoding=UTF-8 -classpath &quot;C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Users\Roman\Desktop\RMI3\out\production\RMI3&quot; Server
Exception in thread &quot;main&quot; java.rmi.ConnectIOException: Exception creating connection to: 192.168.2.21; nested exception is: 
	**&quot;C:\Program Files\Java\jdk1.8.0_144\bin\java.exe&quot; &quot;-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=57417:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin&quot; -Dfile.encoding=UTF-8 -classpath &quot;C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Users\Roman\Desktop\RMI3\out\production\RMI3&quot; Server
Exception in thread &quot;main&quot; 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.&lt;init&gt;(Socket.java:434)
	at java.net.Socket.&lt;init&gt;(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.&lt;init&gt;(Socket.java:434)
	at java.net.Socket.&lt;init&gt;(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

答案1

得分: 1

Server类中,您通过调用LocateRegistry.getRegistry()方法检索远程对象注册表引用。

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

根据错误消息,主机名被推导为192.168.2.21,但在该IP上尝试在端口1099上创建套接字时出现了"Permission denied"错误。

您运行Server类的主机,

该节点是否具有IP地址192.168.2.21?

您可以使用以下命令检查:

ipconfig /all

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

我认为最好您可以尝试将主机名和端口传递给LocateRegistry.getRegistry("127.0.0.1", 1099)方法。更改需要在ServerClient代码中进行。

Server.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();
        }
    }
}

Client.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包中。

Hello.java

package rmi.learning;

import java.rmi.Remote;

public interface Hello extends Remote {
    String Hello() throws RemoteException;
}

HelloClass.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:\Java\jdk1.8.0_261\bin\rmiregistry

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

cd d:\workspace_europa\StackOverflow\bin

start /B  D:\Java\jdk1.8.0_261\bin\java.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:\Java\jdk1.8.0_261\bin\java.exe -classpath .  rmi.learning.Client

输出:

Hello world!

更多调查:

我尝试复现这个问题,我通过路由器连接到互联网。一旦我连接到WiFi,我的路由器会分配IP地址192.168.0.102。
java.net.InetAddress.getLocalHost().getHostAddress() API返回的IP地址是192.168.0.102。

无线局域网适配器 Wi-Fi:

   连接特定的 DNS 后缀 . . . . . : 
   链路本地 IPv6 地址 . . . . . : xxxx::xxxx:xxxx:xxxx:xxxx%18
   IPv4 地址 . . . . . . . . . . . : 192.168.0.102
   子网掩码 . . . . . . . . . . . : 255.255.255.0
   默认网关 . . . . . . . . . . . : 192.168.0.1

如果我尝试将RMI服务绑定到IP地址192.168.0.102的端口1099,那么一切正常。

但是,如果我连接到VPN,我的主机会被分配一个新的IP地址。在连接VPN时,IP地址192.168.0.102不再可解析,并且我的机器IP地址会发生变化。这时,如果我尝试将RMI服务绑定到IP地址192.168.0.102,就会出现错误java.net.SocketException: Permission denied: connect.

因此,如果IP地址对当前节点不再适用,就会出现错误。

我在许多地方看到人们建议使用-Djava.net.preferIPv4Stack=true。在运行Server.class时,您可以尝试类似的操作:

start /B  D:\Java\jdk1.8.0_261\bin\java.exe -Djava.net.preferIPv4Stack=true -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server

有些地方的人还提到要禁用系统上运行的任何防病毒软件,您可以检查一下这种可能性。

英文:

In Server class you are retrieving remote object registry reference by calling LocateRegistry.getRegistry() method.

As hostname and port not passed hence internally hostname will be derived using java.net.InetAddress.getLocalHost().getHostAddress() api.

As per error message hostname is getting derived as 192.168.2.21, but on that IP attempt to create a socket in port 1099 is giving Permission denied error.

The host from where you are running Server class,

Is that node has IP_ADDRESS 192.168.2.21 ?

You may check using

ipconfig /all

You can check using java.net.InetAddress.getLocalHost().getHostAddress() api.

I think better you may try to pass hostname and port to LocateRegistry.getRegistry(&quot;127.0.0.1&quot;,1099) method. Changes are in Server and Client code.

Server.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(&quot;127.0.0.1&quot;, 1099);
			System.out.println(&quot;registry=&quot; + registry);
			registry.bind(&quot;Hello&quot;, Obj);
			System.out.println(&quot;Server is live&quot;);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Client.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(&quot;127.0.0.1&quot;,1099);

        Hello hello = (Hello) registry.lookup(&quot;Hello&quot;);

        String n = hello.Hello();

        System.out.println(n);
    }
}

I have put all classes in rmi.learning package.

Hello.java

package rmi.learning;

import java.rmi.*;

public interface Hello extends Remote {

    public String Hello() throws RemoteException;

}

HelloClass.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 &quot;Hello world!&quot;;
	}
}

Start rmi registry service

start  d:\Java\jdk1.8.0_261\bin\rmiregistry

From a command prompt:
Execute Server

cd d:\workspace_europa\StackOverflow\bin

start /B  D:\Java\jdk1.8.0_261\bin\java.exe -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server

Output:

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

From a command prompt:
Execute Client

D:\Java\jdk1.8.0_261\bin\java.exe -classpath .  rmi.learning.Client

Output:

Hello world!

> More investigation:

I was trying to reproduce this issue, I connect to internet via router. Once I connect to wifi then my router is assigning IP address 192.168.0.102.
java.net.InetAddress.getLocalHost().getHostAddress() api return IP ADDRESS as 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

If I try to bind rmi service to 192.168.0.102 in port 1099 then it's working fine.

But if I connect to VPN then one new IP is assigned to my host. While connected to VPN, IP 192.168.0.102 is no more resolvable and my machine IP_ADDRESS is getting changed. This time if I try to bind rmi service to IP 192.168.0.102 then getting error java.net.SocketException: Permission denied: connect.

Hence the the error is coming if the IP ADDRESS is not no more applicable for current node.

In many places I have seen people are suggesting to use
-Djava.net.preferIPv4Stack=true also. While running Server.class you may try similar

start /B  D:\Java\jdk1.8.0_261\bin\java.exe -Djava.net.preferIPv4Stack=true -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server

Even some places people are saying about disabling any Anti Virus running on the system, you may check that possibility also.

huangapple
  • 本文由 发表于 2020年9月30日 08:31:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/64129370.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定