RMI Registry

rmacher

Mitglied
Hallo

Ich habe mehrere RMI Applikationen, die auf einem Server laufen sollten. Ich kann für jede Applikation jeweils eine Rmi-Registry Instanz (auf einem separaten Port) starten und dann funktioniert es. Jedoch würde ich gerne nur eine einzige RMI Registry Instanz laufen lassen und die RemoteObjects aus unterschiedlichen RMI-Applikationen bei der gleichen RMI Registry Instanz anmelden.

Ist das überhaupt möglich? Alle meine Versuche waren bis jetzt erfolgslos!

Konkret habe ich zwei kleine Test-Applikationen implementiert: die erste liefert Datum (als String) und die zweite die Zeit (als String) zurück.

Die erste Applikation (Date):
Java:
// Interface
package date.server;

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

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

// Implementiertende Klasse 
package date.server;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.text.SimpleDateFormat;
import java.util.Date;

public class RmiDateImpl extends UnicastRemoteObject implements RmiDate {

	private static final long serialVersionUID = 1L;

	public RmiDateImpl() throws RemoteException {

	}

	@Override
	public String localDateAsString() throws RemoteException {
		return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
	}
}

// Server-Klasse 
package date.server;

import java.net.InetAddress;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import javax.swing.JOptionPane;

public class RmiDateServer {

	public static void main(String[] args) {

		int port = 0;
		String remoteObjectName = "dateRO";
		Registry reg = null;

		if (args.length < 1) {
			System.out
					.println("\nusage: java server.RmiDateServer rmiPortNummer");
			System.exit(0);
		} else {

			try {

				port = Integer.valueOf(args[0]);

				System.setProperty("java.security.policy", "rmi.policy");

				if (System.getSecurityManager() == null) {
					System.setSecurityManager(new RMISecurityManager());
				}

				try {
					reg = LocateRegistry.createRegistry(port);
				} catch (Exception e) {
					reg = LocateRegistry.getRegistry(port);
				}

				if (reg != null) {

					RmiDate obj = new RmiDateImpl();

					Naming.rebind(remoteObjectName, obj);

					JOptionPane
							.showMessageDialog(
									null,
									"RMI Date-Server ist bereit für Anfragen von Clients.\n\nServer herunterfahren?",
									"RMI TimeServer ["
											+ InetAddress.getLocalHost()
													.getHostAddress() + ":"
											+ port + "]",
									JOptionPane.QUESTION_MESSAGE);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}

Die Policy-Datei ist (zum Testen) wie folgt:
[XML]
grant {
permission java.security.AllPermission;
};
[/XML]

Die zweite Applikation (Time):
Java:
// Interface
package time.server;

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

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


// Implementierende Klasse 
package time.server;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.text.SimpleDateFormat;
import java.util.Date;

public class RmiTimeImpl extends UnicastRemoteObject implements RmiTime,
		Serializable {

	private static final long serialVersionUID = 1L;

	public RmiTimeImpl() throws RemoteException {

	}

	@Override
	public String localTimeAsString() throws RemoteException {
		return new SimpleDateFormat("hh:mm:ss:SSSS").format(new Date());
	}
}

// Server-Klasse:
package time.server;

import java.net.InetAddress;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import javax.swing.JOptionPane;

public class RmiTimeServer {

	public static void main(String[] args) {

		int port = 0;
		Registry reg = null;

		if (args.length < 1) {
			System.out
					.println("\nusage: java server.RmiTimeServer rmiPortNummer");
			System.exit(0);
		} else {
			try {
				port = Integer.valueOf(args[0]);

				System.setProperty("java.security.policy", "rmi.policy");

				if (System.getSecurityManager() == null) {
					System.setSecurityManager(new RMISecurityManager());
				}

				try {
					reg = LocateRegistry.createRegistry(port);
				} catch (Exception e) {
					reg = LocateRegistry.getRegistry(port);
				}

				if (reg != null) {

					RmiTime obj = new RmiTimeImpl();
					Naming.rebind("timeRO", obj);

					JOptionPane
							.showMessageDialog(
									null,
									"RMI Time-Server ist bereit für Anfragen von Clients.\n\nServer herunterfahren?",
									"RMI TimeServer ["
											+ InetAddress.getLocalHost()
													.getHostAddress() + ":"
											+ port + "]",
									JOptionPane.QUESTION_MESSAGE);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}

Die rmi.policy Datei ist wie bei der ersten Applikation (AllPermission) und steht auch zur Verfügung.


Ich kann eine (beliebige) Applikation starten, jedoch wenn ich die zweite Applikation starte (mit der gleichen RMI Port-Nummer), wird die Ausnahme geworfen.

Hier die Ausnahme:
Java:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
	java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
	java.lang.ClassNotFoundException: time.server.RmiTime
	at sun.rmi.server.UnicastServerRef.oldDispatch(Unknown Source)
	at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
	at sun.rmi.transport.Transport$1.run(Unknown Source)
	at sun.rmi.transport.Transport$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Unknown Source)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
	at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
	at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
	at sun.rmi.server.UnicastRef.invoke(Unknown Source)
	at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
	at java.rmi.Naming.rebind(Unknown Source)
	at time.server.RmiTimeServer.main(RmiTimeServer.java:41)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
	java.lang.ClassNotFoundException: time.server.RmiTime
	at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
	at sun.rmi.server.UnicastServerRef.oldDispatch(Unknown Source)
	at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
	at sun.rmi.transport.Transport$1.run(Unknown Source)
	at sun.rmi.transport.Transport$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Unknown Source)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: time.server.RmiTime
	at java.net.URLClassLoader$1.run(Unknown Source)
	at java.net.URLClassLoader$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.rmi.server.LoaderHandler$Loader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Unknown Source)
	at sun.rmi.server.LoaderHandler.loadClassForName(Unknown Source)
	at sun.rmi.server.LoaderHandler.loadProxyInterfaces(Unknown Source)
	at sun.rmi.server.LoaderHandler.loadProxyClass(Unknown Source)
	at sun.rmi.server.LoaderHandler.loadProxyClass(Unknown Source)
	at java.rmi.server.RMIClassLoader$2.loadProxyClass(Unknown Source)
	at java.rmi.server.RMIClassLoader.loadProxyClass(Unknown Source)
	at sun.rmi.server.MarshalInputStream.resolveProxyClass(Unknown Source)
	at java.io.ObjectInputStream.readProxyDesc(Unknown Source)
	at java.io.ObjectInputStream.readClassDesc(Unknown Source)
	at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
	at java.io.ObjectInputStream.readObject0(Unknown Source)
	at java.io.ObjectInputStream.readObject(Unknown Source)
	... 13 more

Habe auch versucht, RMI Registry aus dem Commandprompt (als separaten Prozess) zu starten, jedoch kommt es gleich.

C:\Temp>rmiregistry 1099

Wenn ich anschliessend z.B. die Date-Applikation starten versuche, bekomme ich wieder das Problem:

Java:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
	java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
	java.lang.ClassNotFoundException: date.server.RmiDate
	at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:419)
	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
	at sun.rmi.transport.Transport$1.run(Transport.java:177)
	at sun.rmi.transport.Transport$1.run(Transport.java:174)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:724)
	at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
	at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
	at sun.rmi.server.UnicastRef.invoke(Unknown Source)
	at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
	at java.rmi.Naming.rebind(Unknown Source)
	at date.server.RmiDateServer.main(RmiDateServer.java:45)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
	java.lang.ClassNotFoundException: date.server.RmiDate
	at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
	at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:409)
	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
	at sun.rmi.transport.Transport$1.run(Transport.java:177)
	at sun.rmi.transport.Transport$1.run(Transport.java:174)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.ClassNotFoundException: date.server.RmiDate
	at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.rmi.server.LoaderHandler$Loader.loadClass(LoaderHandler.java:1206)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:270)
	at sun.rmi.server.LoaderHandler.loadClassForName(LoaderHandler.java:1219)
	at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:729)
	at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:673)
	at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:610)
	at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646)
	at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311)
	at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:255)
	at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1556)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1512)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1769)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
	... 13 more

Meine Frage noch einmal:
Ist so etwas überhaupt möglich? Und falls ja, was mache ich hier falsch?

Ich habe hier den vollständigen Code angegeben und hoffe, dass mir jemand helfen kann. Besten Dank für jeden Hinweis.

P.S.
Habe auch ohne Security-Manager versucht, jedoch das Problem bleibt weiterhin bestehen.
 
Zuletzt bearbeitet:

Ähnliche Java Themen

Neue Themen


Oben