Java RMI bricht ab wenn Remote eine Methode ausgeführt werden soll

Bin gerade etwas am verzweifeln mit RMI. Der StartRegistryAndBind Server läuft auf einem Linux VPS und hat den Port 1099 freigebeben. Der Client auf meinem Windows den ich über die Shell ausführe. Der Code funktioniert lokal ausgeführt und bzgl. remote, wenn ich die "richtige" IP, Namebound und Port eintrage, dann verbindet er sich auch scheinbar mit dem Server nach einigen Sekunden, denn wenn ich den Port oder die IP ändere oder den Server ausschalte, dann kommt sofort die Meldung "Connection refused". Bei korrekten Angaben und laufenden Remote Host kommt quasi "System.out.println("Verbindung...");" auf seitens des Client, aber sobald der Client eine Remote Methode ausführen will bswp. "rs.sayHello()", kommt die unten gezeigte Fehlermeldung. Die Objekt Datei und das Interface liegt sowohl auf Server als auch auf Client Seite ...

Gibt es hier etwas was ich nicht beachtet habe? Gibt es zeitgemäße Tutorials?

Server:

Code:
        try {
            System.setProperty("java.rmi.server.hostname","12.143.141.421");
            LocateRegistry.createRegistry(1099);
            String name="//12.143.141.421/RemoteBookService";
            RemoteService rs = new RemoteService();
            Naming.bind(name, rs);
            System.out.println("Service started");
        } catch (RemoteException e) {
            e.printStackTrace();
            System.out.println("could not start registry");
        }

Client:

Java:
String name = "rmi://12.143.141.421:1099/RemoteBookService";   
       IRemoteService rs = (IRemoteService) Naming.lookup(name);
       System.out.println("Verbindung...");
       rs.sayHello();

Fehlermeldung seitens Client:

java.rmi.ConnectException: Connection refused to host: 12.143.141.421; nested exception is:
java.net.ConnectException: Connection timed out: connect
at java.rmi/sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:626)
at java.rmi/sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:217)
at java.rmi/sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:204)
at java.rmi/sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133)
at java.rmi/java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:215)
at java.rmi/java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:160)
at jdk.proxy1/jdk.proxy1.$Proxy0.sayHello(Unknown Source)
 
Zeitgemäß => RMI wegwerfen und auf was modernes wie Rest setzen 🙂

Anyway, ich hab zwar von RMI keine direkte Ahnung, aber mal gegoolt und mir kommen zwei Dinge komisch vor:

Java:
            String name="//12.143.141.421/RemoteBookService";
Bei bind sehe ich bei allen Tutorials nie, dass da die IP und die // mit angegeben werden. Sprich ich würde es mal mit name = "RemoteBookService" probieren.

Bei lookup sehe ich zumindest in den Tutorials nie da das rmi: davor, sondern direkt das //. Das kann aber egal sein.

Edit: Beispiel: https://www.straub.as/java/rmi/rmi2.html
 
Connection refused kann ansonsten auch bedeuten, dass die Firewall das schlicht blockiert hat. Das muss halt alles richtig freigegeben werden. Und war RMI nicht teilweise auch mit dynamischen Ports und nur der Service Lookup hatte einen festen Port? Ist einfach zu lange her, dass ich damit was gemacht habe …. RMI ist - wie schon gesagt wurde - hoffnungslos veraltet und auch ein Alptraum bezüglich Sicherheit und Datenschutz.
 
Connection refused mit timeout bedeutet ganz eindeutig/klar, dass die TCP-Verbindungsanfrage den Zielhost nicht erreicht, weil sie vorher weggeblockt wurde. Wenn der Zielhost erreicht werden würde und er den Port nur nicht offen/gebunden hat, wäre das ein sofortiger Verbindungsabbruch ohne Timeout.

Und ich schließe mich meinen Vorrednern an: Vergiss RMI! Du verwaltest darüber hoffentlich auch keine verteilten Objektgraphen mit Remote Garbage Collection.

RMI verstehen und eine Alternative dazu bauen war zum Großteil Teil meiner Masterarbeit und ich will dir sagen: RMI solltest und willst du nicht nutzen. Es ist viel zu kompliziert bzw. kann noch sehr sehr viel mehr als du vermutlich brauchst für einfaches RPC. Also HTTP/REST oder HTTP mit gRPC ist heute die Wahl!
 
Vielen Dank für die Rückmeldung, was ist aktuell "state of the art", wenn man ein java Programm auf einem Server laufen lassen will, was dann bspw. vom Client eine JSON entgegennimmt?
 

Zurück
Oben