I've been using RMI for years but now I have a problem I would like to fix on my development PC before I eliminate RMI. (We no longer need RPCs.) I must have mangled something and now RMI only works for me and root (firewall stopped or not). I've been working on this all week and finally tried a simple test program. This was the Oracle Hello RMI example. I stopped and disabled rmiregistry and all Java programs that were running. The other user gets "host:localhost port:1099" then the infamous "Server exception: java.rmi.ConnectException: Connection refused to host." Running the script with sudo connects as expected.
go script
#!/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();
}
}
}
I tried copying the example directory and making everything owned by the other user. I also tried strace on the server but the result looked the same.
More info: The example works for me or root but not for other users. The exception occurs when the server tries to bind to the rmiregistry. I tried other ports. We've used 1099 for years and that's the default if you don't supply a port. I tried with the firewall stopped.
When I have a chance, I'm going to try having root start the server. Our system starts the registry and server at boot.
Thanks