# RMI Connection Problem



## bravedreamer (1. Mai 2005)

Hallo 


Ich habe ein kleines Problem mit RMI. Ich habe einen Server geschrieben (natürlich mit dem zugehörigen Interface), der folgendermaßen gestartet wird: 

```
private static void checkRegistry(int port) throws NAException {

		try {
			reg = LocateRegistry.createRegistry(port);
			System.out.println("New registry created.");
		} catch (RemoteException e2) {
			throw new NAException("Not able to create a registry.", "Port blocked. Registry just running?");
		}
	}
	public static void main (String [] args) {
        	NAimpl na = null;
		int port = 1099;
		String NAName = "NetworkAgent";
		
		// Create and install a security manager
		if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); }

		try {
			checkRegistry(port);
                        //erzeugen des Server Objekts
			na = new NAimpl(NAName, port, false);
			reg.rebind(NAName, na);
			
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (NAException e) {
			System.out.println(e.getMessage() + " Break.");
		}
	}
```

Soweit, so gut. Dieses Fragment startet also einen Server an einem gewissen Port. Frei wählbar. Mit folgendem Befehl versuche ich auf den Server via RMI zuzugreifen: 
	
	
	
	





```
na = (NetworkAgent)LocateRegistry.getRegistry(ip, port).lookup("NetworkAgent");
```

So, ich kann nun zu einigen PC eine Verbindung aufbauen, zu anderen aber nicht. 
Bei den anderen ist eine Firewall installiert (keine Ahnung welche, PC's werden nicht von mir verwaltet), jedoch ist der Port freigeschaltet, zu dem ich mich verbinden will. 

Meine Frage nun: Was mache ich falsch?? Bzw. muss ich noch einen Port freischalten, damit RMI funktioniert??

danke


----------



## Anselmus (2. Mai 2005)

hi,

soweit ich weiß hört der rmi server nur auf 1099. aber es wird für jedes objekt das erzeugt wird, ein neuer port nach belieben von rmi geöffnet... 

gtx
stephan


----------



## bellmann29 (2. Mai 2005)

Hallo,

wenn Du zu dem Rechner, auf dem der RMI-Server läuft eine Verbindung aufbauen kannst, ist doch alles in Ordnung. Was willst Du denn auf anderen Rechnern?
Ziel eines Servers ist es doch, dass alle Clients auf genau diesen einen zugreifen, und nicht auf irgendeinen Rechner.
Irgendwie solltest Du Dein Problem nochmals genauer und evtl. Fehlermeldungen oder ähnliches posten.

Bis dann.


----------



## bravedreamer (2. Mai 2005)

Es ist so: Mein Programm kopiert die Sourcefiles des RMI-Servers auf einen bestimmten Rechner (von Benutzer frei wählbar). Dieser RMI-Server wird dann gestartet. Die Aufgabe des Servers ist es, Systemeigenschaften zu protokollieren. Von Zeit zu Zeit fragt der Client diese Systemeigenschaften ab. 
So, das ist alles was gemacht wird. 

Nochmal zu Problem: Ich transferiere den Sourcecode mit ssh auf den anderen Rechner und starte dort den Server. Dieser läuft und wartet an einem gewissen Port (siehe Quelltext weiter oben). 
Der Client verbindet sich nun mit dem Server. Es geht aber nicht, da eine Firewall existiert. 

Frage nun: Muss ich mehr als nun den Port für den Server an meinem Rechner freischalten??


----------



## bellmann29 (2. Mai 2005)

Hallo,

es sollte genügen, nur den Port für die Registry (default 1099) zu öffnen.

Bis dann


----------



## bravedreamer (4. Mai 2005)

Ich habe nun ein kleines Testprogramm das RMI verwendet erstellt. Das geht aber auch nicht. Weiß zufällig jemand, wie man testen kann, ob ein Port offen ist, oder nicht.


danke


----------



## bellmann29 (4. Mai 2005)

Hallo bravedreamer,

Du schreibst schon wieder, "... es funktioniert nicht...", Du hast aber Deinen Rechner eingeschaltet, oder?

Um Dir zu helfen benötigen die Leser des Forum schon einiges mehr als die Aussage, daß Dein Prog nicht funktioniert.
Da Du scheinbar nicht in der Lage bist, Dein Problem genauer zu beschreiben, wäre es schon hilfreich, wenn Du mal die Exception-Ausgabe postest.

Dem könnte man dann mehr entnehmen, als das es nicht "funktioniert".

Dein kleines RMI kannst Du auch mal posten. Aber erst die Exception.

Danke


----------



## bravedreamer (5. Mai 2005)

Sorry. Ich glaubte eine simple TimeoutException könnte Euch nicht weiterhelfen.

Bezüglich meines Problems: Ich kann mich nicht mit meinem Server verbinden. Dieser läuft auf einem anderen Rechner in einem getrennten Netzwerk mit Firewall. Laut Systemadmin ist der Port 1099 freigeschaltet. Der Verbindungsaufbau "funktioniert aber nicht", da ich die besagte Exception erhalte.

Exception:
java.rmi.ConnectException: Connection refused to host: 138.232.66.157; nested exception is:
        java.net.ConnectException: Connection timed out
        at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:567)
        at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
        at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:101)
        at systest.testRMI.Server_Stub.t(Unknown Source)
        at systest.testRMI.TestClient.main(TestClient.java:43)
Caused by: java.net.ConnectException: Connection timed out
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:305)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:171)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:158)
        at java.net.Socket.connect(Socket.java:452)
        at java.net.Socket.connect(Socket.java:402)
        at java.net.Socket.<init>(Socket.java:309)
        at java.net.Socket.<init>(Socket.java:124)
        at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)

Der Testserver sieht so aus: 

```
public class Server extends UnicastRemoteObject implements TestServer {
	private static Registry reg = null;
	private String name;
	
	public Server(String name) throws RemoteException {
		super();
		this.name = name;
	}

	public void t() throws RemoteException {
		new Thread(new Runnable() {
			  public void run() {
			    try {
			      Thread.sleep(2000);    // z.B. 2 Sekunden warten
			      terminate();
			    }
			    catch(InterruptedException e) {	e.printStackTrace();
			    } catch (RemoteException e) { e.printStackTrace();}
			  }
			}).start();		
	}
	
	private void terminate() throws RemoteException {
		System.exit(0);
		System.out.println("Termination complete.");
	}
	
	private static void checkRegistry(int port) throws RemoteException {
		reg = LocateRegistry.createRegistry(port);
	}

	public static void main(String[] args) {
		Server na_test;
		int port = 1099
		String agentName = "TestAgent";
		
		try {
			checkRegistry(port);
			na_test = new Server(agentName);
			System.out.println("Bind Server to port: " + port);
			reg.rebind(agentName, na_test);
			System.out.println("Server bound in registry. Start successful.");

		} catch (RemoteException e) {
			e.printStackTrace();
		}
        }
}
```

Der TestClient sieht so aus:

```
public class TestClient {
	public static void main(String[] args) {
		TestServer na1;
		int port = 1099
		String ip = "irgendeineIP";
		
		// Create and install a security manager
		if (System.getSecurityManager() == null) {
			System.setSecurityManager(new RMISecurityManager());
		}
		
		try {
		
			System.out.println("Trying to locate the agent at ip: " + ip + "; port: " + port);
			na1 = (TestServer)LocateRegistry.getRegistry(ip, port).lookup("TestAgent");
			na1.t();
			System.out.println("Termination erfolgreich.");
		} catch (RemoteException e) {
			e.printStackTrace();
			System.out.println(e.getCause().getMessage());
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
```

So, vielleicht hilft Euch das weiter. 
Hoffe alle Fragen wurden hiermit geklärt.


----------



## Bleiglanz (5. Mai 2005)

1099 ist doch nur die Registry??

Es gibt da nämlich eine Registry UND deinen Dienst....


----------



## bellmann29 (6. Mai 2005)

Hi,

hast Du jemals die Server-Klasse ausgeführt in der IDE? So wie es für mich aussieht, ist nach dem durchlaufen der main-Methode der Thread beendet und "basta". Dann ist Schluß. Nichts laüft mehr. Entweder Du startest in der main-Methode einen eigenständigen Thread oder Du sorgst dafür dass sie nicht beendet.

Die Timeout-Exception gibt Auskunft darüber, daß das Programm mehrmals einen Connect zum "Server" versucht hat aber keine Gegenstelle gefunden hat und andere Fehler sind erstmal auszschließen.

Wieso installierst Du Server, die nicht funktionieren, auf entfernten Rechnern ohne sie vorher zu testen (so scheint es mir jedenfalls).

Die Methode t() solltes Du ändern. Warum rufst Du nicht gleich terminate() auf? Du wills ja nur etwas beenden. Allerdings ist da gar kein Prozess der läuft und keine VM die mit System.exit(0) beendet werden kann.
Bringt das System.out.println(...) nach dem System.exit(0) noch etwas? Habe so etwas noch nie ausprobiert. Aber ich tu es heut noch garantiert.

Also bitte das oben gesagte überdenken, ändern. Vorher lokal testen. Mehrfach!!!!

Die Metoden in RemoteObjecten sind "Service-Methoden", sie bedienen den Client und rufen sich nicht gegeseitig auf. (t() --> terminate()).

Sie Dir andere Server-Programme an um mehr zu lernen.

Bis dann.

Tip: wenn Du versuchst durch "irgendeineIP" im Client-Code die IP-Adresse nicht zu posten, mußt Du auch "138.232.66.157" aus dem Exception-Text rausnehmen.


----------



## bellmann29 (7. Mai 2005)

Hi,

da war ich wohl wieder zu voreilig mit meinen Behauptungen. Habe jezt mal Deinen Code "abgeschrieben" und probiert.

Der Thread wird doch nicht einfach beendet. Läuft also weiter.

Habe auch versucht eine Verbindung aufzubauen, wenn auch nur mit telnet um zu sehen, ob auf 1099 gelauscht wird. Und tatsächlich werden dort verbindungen erwartet und angenommen.

Damit entschuldige ich mich für die falschen Gedanken im vorigen Posting.  

Wenn auch nicht alles falsch war.

Wie/wer startet den Server-Process auf der anderen Seite? Dem entfernten Rechner? Kannst Du überprüfen ob der Server-Process tatsächlich läuft oder mußt Du Dich auf jemand anderen verlassen?

Werden dann beim start dessen irgendwelche Probleme angezeigt?

Dem Timeout entsprechend läuft auf dem entfernten Rechner nichts.

Also vielleicht doch mal schauen, was dort passiert.

Bis dann.


----------



## Guest (9. Mai 2005)

Meine Debugging-Methode ist folgende:
Ich logge mich via ssh auf dem anderen Rechner ein und starte dort manuell den Server um dessen Ausgaben zu sehen. Wenn der Server funktioniert, wird dieser dann per script gestartet.

Beim Starten des Servers werden keine Fehlermeldungen ausgegeben. Nur die 2-3 Ausgaben von mir selbst.

Bezüglich des Timeouts: Ich habe jetzt mal probiert das Programm 'rmiregistry' aufzurufen. Dieser Aufruf startet die Registry an dem Port 1099. Danach versuchte ich programmtechnisch einen Socket zur angegebenen IP und Port aufzustellen, jedoch wird auch dieser mit einer TimeoutException zurückgewiesen. Ich vermute, dass der Port nicht offen ist. Das liegt jedoch nicht in meiner Hand.


danke jedenfalls


----------



## Anselmus (9. Mai 2005)

hi,

du mußt erst rmiregistry starten und dann dein serverprogramm, sonst kann sich dein programm ja niergends registrieren...

gtx
stephan


----------



## Bleiglanz (10. Mai 2005)

> Bezüglich des Timeouts: Ich habe jetzt mal probiert das Programm 'rmiregistry' aufzurufen. Dieser Aufruf startet die Registry an dem Port 1099. Danach versuchte ich programmtechnisch einen Socket zur angegebenen IP und Port aufzustellen, jedoch wird auch dieser mit einer TimeoutException zurückgewiesen. Ich vermute, dass der Port nicht offen ist. Das liegt jedoch nicht in meiner Hand


Du hast jetzt erst probiert die rmiregistry aufzurufen?! Was hast du denn vorher gemacht??


----------

