RMI Problem mit Eclipse (UnmarschalException und ClassNotFoundException)

Zerwas

Mitglied
Hallo Leute,

ich arbeite mit:
- java jdk1.5.0
- eclipse 3.0.0
- OS: Windows XP.

Ich habe einen Server auf Rmi basis geschrieben. Dieser Server ist mit zwei Clienten verbunden einer davon ist Standalone und der andere ist in der Eclipse-Umgebung eingebaut.
Der Server funktioniert Folgendermassen:
der Standalone Client meldet sich beim Server und sagt ihm welche Objecte er zur verfügung stellen soll. Der Server erstellt eine ArrayList mit den Namen aller, zur verfügung gestellten, Objecten und speichert die Objecte auf der Festplatte. Der Client der in der Eclipse-Umgebung lässt sich vom Server die Liste mit allen Objecten geben und fordert dann die für ihn Interessanten Objecte an.

Mein Problem:
Der Austausch von Daten zwischen dem Standalone Client und dem Server funktioniert einwandfrei. Aber bei dem Austausch mit dem Clienten in der Eclipse-Umgebung funktioniert nur die Übergabe der ArrayList, bei den Objecten kriege ich folgende FehlerMeldung:

Code:
java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
	java.lang.ClassNotFoundException: serverObject (no security manager: RMI class loader disabled)
	at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:162)
	at ...
Caused by: java.lang.ClassNotFoundException: serverObject (no security manager: RMI class loader disabled)
	at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:371)
	at

Darauf hin habe ich probiert einen RMISecurityManager einzubinden mit folgendem Code:
Code:
if (System.getSecurityManager() == null) {
                      System.setSecurityManager(new RMISecurityManager());
                      }

Dieses hat mir dann Folgende Fehlermeldung geworfen:
Code:
java.security.AccessControlException: access denied (java.net.SocketPermission 192.168.0.7:1130 connect,resolve)
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
	at ...

Ich habe dann noch weiter mit SocketPermisson und RMIClassLoader probiert, kam aber zu keinem ergebniss.

Ich hoffe einer von euch hat eine Idee was ich falsch gemacht oder übersehen habe.

mfg
Mathias Buchallik
 
Ich habe es mittlerweile geschafft, die in den Klammern stehenden Fehlermeldungen: (no security manager: RMI class loader disabled), und die Fehlermeldung access denied durch dass erstellen einer Policy datei zu unterbinden.
Aber nach wie vor habe ich noch die UnmarschalException mit der ClassNotFoundException und ich habe immer noch keine Ahnung woran das Liegt.
 
hallo!

Ohne jetzt deinen Quellcode gesehen zu haben könntest du ja mal folgende Punkte checken:
public class UnmarshalExceptionextends RemoteExceptionAn UnmarshalException can be thrown while unmarshalling the parameters or results of a remote method call if any of the following conditions occur:

if an exception occurs while unmarshalling the call header
if the protocol for the return value is invalid
if a java.io.IOException occurs unmarshalling parameters (on the server side) or the return value (on the client side).
if a java.lang.ClassNotFoundException occurs during unmarshalling parameters or return values
if no skeleton can be loaded on the server-side; note that skeletons are required in the 1.1 stub protocol, but not in the 1.2 stub protocol.
if the method hash is invalid (i.e., missing method).
if there is a failure to create a remote reference object for a remote object's stub when it is unmarshalled.

... du könntest aber auchmal versuchen mittels des Properties java.rmi.server.codebase deiner Server Variante mitzuteilen wo es die Client Interfaces suchen soll ...

btw: http://www.tutorials.de/forum/showthread.php?t=179039

Gruß Tom
 
Danke Tom,

die Probleme waren:
1.
Aus einem mir unbekannten Grund muss der Thread, der sich in die RMI-Verbindung einklingt ein Statischer Thread sein und (ist nur eine Vermutung) von einer Statischen funktion aus aufgerufen werden.


2.
Die Class die ich über die RMI-Leitung schicke muss einmalig sein, heißt dass beim Casten zum Object die ID der letzten Compilierung geprüft wird und wenn die sich unterscheidet wirft er eine InvalidCastException.


Soweit läuft jetzt auch alles. Ein neues Problem ist, dass wenn ich den Server nicht mit Eclipse Starte sondern als .jar mit einer .bat starte kriege ich beim benutzen eines Clienten(jetzt egal welcher) eine ClassNotFoundException.

mfg
Mathias Buchallik

P.S.
Ich kann leider keine Quellen posten, da dieses ein Projekt für meine Firma ist und diese darauf besteht, die Quellen verschlossen zu halten.
 
Ich habe vergessen die Frage zu stellen:

Wie unterscheidet sich der Aufruf von eclipse zu einem Aufruf von einer .jar.
Wobei schon klar ist, dass ich bei einer .jar die Aufruf-Parameter komplett selbst übernehmen muss.
 
OK ich hab das Problem gelöst, Ich hab in der .bat die Main über den Befehl -jar main.jar aufgerufen, ich musste aber die .jar nur im ClassPath angeben und die Main-Klasse direct aufrufen.
Bsp für .bat:
cd D:\Server
java -classpath main.jar;swt.jar de.haupt.main
 
Ich habe die gleichen Probleme und versuche seit Tagen dieses zu lösen :-(

In Eclipse habe ich einen Server- und einen Client-Plugin (der dependent vom Server-Plugin ist - also diese Klassen via RMI aufruft...) eingerichtet.

Problem 1:
Das der Client überhaupt nicht startet, weil er die Klassen im anderen Plugin nicht findet habe ich so gelöst:

Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());

Führe ich jedoch eine RMI-Aktion aus, dann gibt's ein ClassNotFoundException. Der Aufruf über Eclipse mit den Argumenten "-Djava.security.manager -Djava.security.policy= myPol.policy" wirf diesen Fehler aus:
AccessControlException: access denied

Da ich nicht weiß wie man ein Policy-File (mit dem Policytool) erstellt, um ALLE Rechte zu erstellen, habe ich eine EclipsePolicy erstellt und diesem einen neuen SecurityManager übergeben:

SecurityManager sm = new SecurityManager();
// get the list of codesource URLs to grant AllPermission to
Policy eclispePolicy = new EclipsePolicy(Policy.getPolicy());
Policy.setPolicy(eclispePolicy);
System.setSecurityManager(sm);

Somit habe ich das code-mäßig gelöst, ohne java -Djava.security.manager -Djava.security.policy= myPol.policy aufzurufen

Jetzt bekomme ich Client-Seitig eine Fehlermeldung.

Auf den Client beschwert er sich, dass er eine Klasse (im Server - wie Eingangs-Problem 1) nicht findet.

Weiter stellt er fest, daß die Klasse (gesendet vom Server) nicht kompatibel (kann nicht casten) mit der Client-Klasse ist. Alle Klassen befinden sich doch in Eclipse, wie kann dann die gleiche Klasse unterschiedliche IDs haben? Liegt das vielleicht daran, dass ich den Server als "Java-Applikation" unte Eclipse starte und den Client als "Runtime-Workbench" und beide verwenden unterschiedliche ClassLoader (Java und Eclipse)?

Kann ich das lösen wenn ich einen statischen Thread verwendet? Und wie sieht das aus?

Oder besser: wie kriege Eclipse so zu laufen wie ich es möchte?

Gruss,
Tai
 
Hallo tai,

Da ich nicht weiß wie man ein Policy-File (mit dem Policytool) erstellt, um ALLE Rechte zu erstellen, habe ich eine EclipsePolicy erstellt und diesem einen neuen SecurityManager übergeben:

Eine Policy-Datei ist eigentlich bloß eine Text-datei. Um volle rechte zu erhalten, musst du folgenden Code eintragen:
Code:
grant
{
permission java.security.AllPermission;
};

Weiter stellt er fest, daß die Klasse (gesendet vom Server) nicht kompatibel (kann nicht casten) mit der Client-Klasse ist. Alle Klassen befinden sich doch in Eclipse, wie kann dann die gleiche Klasse unterschiedliche IDs haben?

Die ID die hier unterschiedlich ist, ist die Id der Compilierung. Jedes mal wenn eine source Compiliert wird, wird ihr eine ID gegeben.
Du musst dabei darauf achten, dass der Client dieselbe Version hat wie der Server.
Es kann auch sein, das Eclipse die klassen nicht findet. Eclipse-plugins finden nur die Klassen die in Ihrem eigenen Projeckt sind oder in anderen Plugins.
ACHTUNG: Dieses gilt nicht, wenn du dein Plugin in der Eclipseumgebung Startest.

mfg
Mathias Buchallik
 
Ich verstehe ich nicht ganz. Beide Plugins starte ich in der Eclipse-Umgebung. Den Server-Plugin als "Run as>Java-Applikation" und den Client als "Runtime Workbench".

Eclipse findet auch die Klasse und die kompilierte Klasse befindet sich im Server-Plugin, d.h. der Client müsste die auch nehmen. Die Klasse befindet sich auch in keiner angegebenen library bzw. in keinem jar?!

In meinem Client-code bekomme ich ein serializable Object vom Server vom Typ MyClass aber "object instanceOf MyClass" gibt immer false! Habe mal als output den Hashcode beider Klassen ausgegeben und diese sind unterschiedlich?!:
object.getClass().hashCode()
MyClass.getClass().hashCode()

Auf der einen Seite findet Eclipse diese Klasse via RMI (aber anscheinend mit einer falschen ID) und andererseits findet er ganz normale Klassen aus meiner Library nicht (wie z.B. org.apache.log4j.Logger), obwohl ich die Library in den Server- und Client-Plugin eingebunden habe. Im Plugin-Manifest des Clients habe ich auch den Server-Plugin als Dependency eingefügt.

Server-seitigt läuft alles einwandfrei. Es ist nur der Client der meckert. Glaube nah dran zu sein ;-)

Ach ja, wie funktioniert das mit dem statischen Thread? Könnte das mal probieren...
 

Neue Beiträge

Zurück