You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Hello RMI示例仅本人及root可用,其他用户无法使用?

RMI仅本人及root账户可用的问题排查求助

我使用RMI已有多年,目前在开发机上遇到一个问题,希望在移除RMI(我们不再需要RPC)前解决。不知哪里配置出错,现在RMI仅本人及root账户可用(无论防火墙是否关闭)。我耗时一周排查,最终测试了Oracle的Hello RMI示例:停止并禁用了rmiregistry及所有运行的Java程序,但其他用户执行时会先显示"host:localhost port:1099",随后触发知名错误"Server exception: java.rmi.ConnectException: Connection refused to host.",而使用sudo运行脚本则可正常连接。

测试启动脚本

#!/bin/bash
#
#

port="$1"
[[ $port = "" ]] && port="1099"

ip="localhost"
#ip="127.0.0.1"

#sudo systemctl stop rmiregistry

while true; do sudo netstat -a --numeric-ports|grep $port; if [ $? -eq 0 ]; then echo -e "$port is in use - waiting"; sleep 1; else break; fi; done

JAVA_BIN="/usr/java/jdk/bin"

$JAVA_BIN/javac -d "." *.java

$JAVA_BIN/rmiregistry $port &
rmiregistryPID=$!
echo -n "rmiregistry:";ps -p $rmiregistryPID

classDir="."

#strace
$JAVA_BIN/java -classpath $classDir \
    -Djava.rmi.server.codebase=file:$classDir/ \
    -Djava.rmi.server.hostname=$ip \
    example.hello.Server $ip $port &
serverPID=$!
echo

sleep 5;echo -e "\nServer PID:";ps -p $serverPID

$JAVA_BIN/java  -classpath $classDir example.hello.Client $ip $port
clientPID=$!;kill $clientPID

echo
kill $rmiregistryPID; ps -p $rmiregistryPID
kill $serverPID;ps -p $serverPID

Hello.java

package example.hello;

import java.rmi.Remote;
import java.rmi.RemoteException;

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

Server.java

package example.hello;

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Server extends UnicastRemoteObject implements Hello {

    public Server() throws RemoteException {}

    public String sayHello() throws RemoteException {
        try {
            return "Hello, world!";
        } catch (Exception ex) {
            System.err.println("Server exception: " + ex.toString());
            ex.printStackTrace();
            return "error";
        }
    }

    public static void main(String args[]) {

        try {
            String host = (args.length < 1) ? "127.0.0.1" : args[0];
            String portString = (args.length < 2) ? "1099" : args[1];
            int port = Integer.parseInt(portString);
            System.out.println("host:"+host+" port:"+port);

            Server obj = new Server();

            //LocateRegistry.createRegistry(port);
            String name = "//"+host+":"+port+"/Hello";
            Naming.rebind(name, obj);
            System.out.println("Server ready; host:"+host+" port:"+port);
        } catch (Exception ex) {
            System.err.println("Server exception: " + ex.toString());
            ex.printStackTrace();
        }
    }
}

Client.java

package example.hello;

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

public class Client {

    private Client() {}

    public static void main(String[] args) {

        String host = (args.length < 1) ? null : args[0];
        String portString = (args.length < 2) ? "1099" : args[1];
        int port = Integer.parseInt(portString);
        System.out.println("host:"+host+" port:"+port);
        try {
            Registry registry = LocateRegistry.getRegistry(host, port);
            Hello stub = (Hello) registry.lookup("Hello");
            String response = stub.sayHello();
            System.out.println("\nresponse: " + response);
        } catch (Exception e) {
            System.err.println("Client exception: " + e.toString());
            e.printStackTrace();
        }
    }
}

已完成的排查动作

  • 复制示例目录并将所有内容改为其他用户所有,结果无差异
  • 对服务器进程使用strace分析,未发现异常线索
  • 尝试切换其他端口测试,问题依旧;默认1099端口已使用多年
  • 关闭防火墙测试,问题未解决

补充说明

示例仅本人及root账户可正常运行,异常触发点在服务器尝试绑定到rmiregistry时。后续计划尝试由root启动服务器(我们的系统原本会在开机时自动启动注册表及服务器)。

内容的提问来源于stack exchange,提问作者William Dickerson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 08:10:56