Serialisiertes Objekt über Socket nachladen

Treavor

Mitglied
Moin,

ich hoffe mal ich hab das richtige Forum getroffen.
Ich möchte einen mobilen Agenten basteln. Dafür wird zwischen zwei Rechnern eine Netzwerkverbindung aufgemacht und dann wird die .class des Agenten auf den Zielrechner übertragen. Danach wird das serialisierte Objekt des Agenten übertragen und auf dem Zielrechner wieder zusammen gebaut. (heißt einfach nur, dass das Objekt jetzt auf einem Rechner existiert auf dem vorher keine .class vorhanden war)
Das übertragen der .class funktioniert und auch das Laden dieser funktioniert. Jetzt scheitert es nur noch am Laden der serialisierten Daten - und langsam hab ich da so lange draufgestarrt, dass ich keine Ahnung mehr habe wodran es liegen könnte. Wäre super wenn jemand von euch mal kurz drüber schauen könnte.

Empfangen auf dem Zielrechner (serialisierter Kram ab Zeile 21):
Java:
ServerSocket socket = new ServerSocket(port);
Socket client = socket.accept();	
DataInputStream in = new DataInputStream(client.getInputStream());
	               
// dann kommen der Klassenname und die Größe der .class
String klassenname = in.readUTF();
int paketgroesse   = in.readInt();
	
// die Daten der .class empfangen
byte[] classfile_bytes     = new byte[paketgroesse];
in.readFully(classfile_bytes);		
              
// empfangene Klasse laden
MyClassLoader cl = new MyClassLoader(classfile_bytes); // der eigene ClassLoader tut nicht mehr als das byte[] an defineClass weiterzureichen

Class<?> cls = cl.findClass("A01_Heimkontext.Agent");
cls = cl.loadClass("A01_Heimkontext.Agent");     // kann auch wieder raus, weil ändert nichts
	            
// ###################################                         
// nun die serialisierten Daten empfangen und daraus ein Objekt machen
ObjectInputStream in_ser = new ObjectInputStream(client.getInputStream());
System.out.println( in_ser.available() );  // -> und hier kommt immer nur 0 raus
Object obj = in_ser.readObject();           // -> und hier bricht er dann ab
// ###################################
	            
in.close();
in_ser.close();
client.close();	// brav wieder alles schließen
socket.close();

// Der Agent ist gelandet und kann jetzt seine Arbeit vollrichten 
Method m = obj.getClass().getMethod("tuWasTolles");
m.invoke(obj);


Der Sendenteil vom anderen Rechner (auch ab Zeile 21):
Java:
String klassenname = this.getClass().getSimpleName();

Socket verbindung = new Socket(ip, port);                  
DataOutputStream out = new DataOutputStream( verbindung.getOutputStream() );
                    
out.writeUTF( klassenname );        // schicke den Klassennamen (Agent)
out.flush();
                    
// .class öffnen und den byte-puffer erstellen
FileInputStream classfile = new FileInputStream("bin/"+paketname+"/"+klassenname+".class");
classfile_bytes = new byte[ classfile.available() ];   // puffer erstellen
                        
out.writeInt( classfile.available() );  // erstmal schicken wie viele Bytes übertragen werden sollen

classfile.read( classfile_bytes );      // Inhalt der .class in den Puffer
classfile.close();
out.write( classfile_bytes  );          // Inhalt des Puffers rausschicken
                     
// ###################################
// einen ObjectStream öffnen um die serialisierten Daten zu übertragen
ObjectOutputStream out_ser = new ObjectOutputStream(verbindung.getOutputStream());
out_ser.writeObject(this);
out_ser.flush();
out_ser.close();
// ###################################


die wichtigen Teile sind zwischen den ###
wie gesagt, das Laden der Klasse funktioniert (ich kann .newInstance machen und dann läuft das auch - nur fehlen dann die Werte in den Variablen). Problem ist dass er aus einem mir nicht ersichtlichen Grund die serialisierten Daten nicht empfängt ( in_ser.available() ist immer 0 - in.available() ist 257).

Ich würde mich riesig freuen wenn mir jemand von euch einen Tipp geben kann wo ich suchen muss, weil so langsam macht das keinen Spass mehr.

Vielen Dank,
Daniel
 

Empire Phoenix

Top Contributor
Denke das problem liegt darin, das du mehrere InputStreams zugleichv erwendest, immer nur den höhsten (in deinem fall der ObjectinputStream ) verwenden. Der sollte eigentlich auch die benötigten functionen der tieferliegenden zur verfügung stellen.

Am rande, du bist glaube ich die erste Person die tatsächlich mobile Agents benutzt, ohne würmer zu schreiben ^^.
 

Treavor

Mitglied
man programmiert halt das was der Prof in den Übungen gern sehen will ;-)

Das mit dem Stream hab ich geändert - jetzt läuft alles über ObjectInputStreams (bzw Output). Das Problem ist dadurch aber leider nicht verschwunden.

kurzer Ausschnitt aus meinen aktuellen experimenten (Senderseite):
Java:
out_ser.writeUTF("EndBinary");
out_ser.flush();

out_ser.writeObject(this);
out_ser.flush();
                    
out_ser.writeUTF("EndSerial");
out_ser.flush();
System.out.println("fertig");

das EndBinary wird in jedem Fall übertragen und der Empfänger empfängt es auch.

Dann sollte er das Objekt schicken, aber der Empfänger bekommt nichts. Ich hab beim Empfänger ein while( in.available() == 0); gemacht und da bleibt er hängen.
Auf Senderseite sieht es aber so aus als sei das Objekt geschickt worden - er kommt bis zum sys.out("fertig")

Wenn ich das .writeObject(this) auskommentiere dann ist alles toll und es kommt auch das EndSerial an.

Normalerweise würd ich jetzt anfangen daran zu zweifeln, dass das .writeObject(this) funktioniert, aber ich hatte es schonmal soweit dass es lief - also das übertragen von serialisierten Daten funktioniert so (und nein, ich kann nicht zu dem Punkt zurück an dem es lief ;) )
 
S

SlaterB

Gast
auf in.available() kannst du dich nunmal nicht verlassen, Punkt, Aus,
verwende anderen Code und poste vor allem die aktuelle Version des Empfängers
 

Treavor

Mitglied
ok, also nehm ich das mit available() wieder raus. Dadurch sieht er jetzt wieder so aus wie im Eingangspost.
Aber was meinst du mit "anderen Code"? Ich weiß ja eben nicht wie ich das anders machen könnte.


Aber jetzt kommt ne Fehlermeldung auf der Empfängerseite mit der ich ebenfalls nix anfangen kann:
Java:
java.lang.ClassNotFoundException: A01_Heimkontext.Agent
	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.misc.Launcher$AppClassLoader.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 java.io.ObjectInputStream.resolveClass(Unknown Source)
	at java.io.ObjectInputStream.readNonProxyDesc(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)
	at A01_Arbeitskontext.Arbeitsserver.main(Arbeitsserver.java:23)

die entsprechende Zeile ist:
[JAVA=23]Object obj = in_ser.readObject();[/code]
(siehe auch Empfänger-Code im ersten Post - Zeilennummern passen)
 
S

SlaterB

Gast
ObjectInputStream in_ser = new ObjectInputStream(client.getInputStream());
Object obj = in_ser.readObject();

passt ja kaum zum Sende des
out_ser.writeUTF("EndBinary");
VOR dem Objekt, daher frage ich mich ob du da andere read-Befehle eingebaut hast,

und ja, einfach nur lesen ohne available() war auch meine Intention für einfachen lauffähigen Code,
hinsichtlich available()-Alternativen kann nicht nichts nennen,

die Klasse des gesendeten Objekts muss auch beim Empfänger bekannt sein, sonst gehts nicht,
höhere Tools wie RMI oder WebService können glaube ich automatisch benötigte Klassen übertragen,
ansonsten bleibt dir nur die Übertragung einfacher ints, Strings, Listen, XML-Text usw.
 

Treavor

Mitglied
den Sender hab ich auch wieder in den ausgangszustand zurück gebaut. Da hab ich aufgepasst, dass lesen und schreiben immer den selben Typ haben (nicht UTF schreiben und Object lesen).


trotzdem noch mal die aktuelle Version
Java:
ObjectInputStream in_ser = new ObjectInputStream(client.getInputStream());
	            
// dann kommen der Klassenname und die Größe der .class
String klassenname = in_ser.readUTF();
int paketgroesse   = in_ser.readInt();
	
// .class vom Socket lesen
byte[] classfile_bytes     = new byte[paketgroesse];
in_ser.readFully(classfile_bytes);		// vom Socket in den Puffer

// empfangene Klasse laden        
MyClassLoader cl = new MyClassLoader(classfile_bytes);

Class<?> cls = cl.findClass("A01_Heimkontext.Agent");
cls = cl.loadClass("A01_Heimkontext.Agent");
Object obj = cls.newInstance();

obj = in_ser.readObject();

// Der Agent ist gelandet und kann jetzt seine Arbeit vollrichten
Method m = obj.getClass().getMethod("tuWasTolles");
m.invoke(obj);

die .class wird empfangen und in Zeile 16 wird ein Objekt davon erstellt (im Konstruktor ist ein println und das wird auch ausgegeben). Davon ab dass es unsinnig ist das Objekt 2 Zeilen später wieder überschreiben zu wollen (was ja aber eh nich funktioniert). Damit müsste die Klasse doch bekannt sein.

Ansonsten ist das übertragen der einzelnen Variablen auch ne Idee (serialisierte Daten wären schöner, aber wenn es halt nicht anders geht) - kam mir bisher gar nicht in den Sinn.
 

Treavor

Mitglied
ich glaub ich hab so grob verstanden wo das Problem mit meinem Classloader liegt, allerdings bekomm ich es auch mit Hilfe etlicher Beispiele aus dem Netz nicht zum Laufen. Und weil ich keine Lust hab da noch einen Tag mit zu verschwenden hab ich das jetzt so umgebaut dass die Daten einzeln als Strings und Integer rüber geschickt werden - ganz ohne serialisieren. Funktioniert jetzt so auf jeden Fall.
trotzdem vielen Dank für die Hilfe :)


edit: gut, ich hab mich des Themas doch nochmal angenommen und im Nachhinein kann ich nicht mehr so richtig nachvollziehen warum es bei mir gestern Abend nicht mehr funktioniert hat.
Der Link den SlaterB rausgesucht hatte war schon genau der richtige und hier (vorletzter Post) hab ich das auch nochmal gefunden.
Im Grunde wirklich nur ne neue Klasse erstellen die den ObjectinputStream erweitert und dann die ganze Kommunikation über diesen neuen Stream laufen lassen (nur copy'n'paste aus dem sun-forum) . Da die Klasse den selbst gebauten ClassLoader kennt, kann sie mit readObject() die serialisierten Daten entgegen nehmen und sie richtig zusammen setzen.
Wenn man den neuen Stream erstmal hat und gehts quasi automatisch...
Auf jeden Fall nochmal vielen Dank :toll:
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
Thallius Hash über serialisiertes Objekt? Allgemeine Java-Themen 3
Developer_X Input/Output Serialisiertes Objekt speichern und laden Allgemeine Java-Themen 1
P Serialisiertes Objekt innerhalb einer XML Node Allgemeine Java-Themen 25
Thallius Serialisiertes File kann auf anderem Rechner nicht geladen werden Allgemeine Java-Themen 12
N Lwjgl 3d Objekt wird schmaler, wenn es sich dreht Allgemeine Java-Themen 0
B Ein Objekt einer Klasse mehreren anderen Klassen zur Verfügung stellen? Allgemeine Java-Themen 6
T Objekt Array Aufgabe mit Busdatenbank Allgemeine Java-Themen 2
Maxi-JOO Klassen Dummy Objekt in anderen Constructor übergeben Allgemeine Java-Themen 5
el_niiinho13 Objekt auf der Konsole ausgeben lassen Allgemeine Java-Themen 8
d.lumpi Aus Einer Klasse auf ein Objekt einer anderen Klasse Zugreifen Allgemeine Java-Themen 1
A Objekt aus anderen Objekten machen Allgemeine Java-Themen 8
SaftigMelo In einem Winkel Objekt bewegen Allgemeine Java-Themen 2
E Datentypen Wie kann ich die Längen der unterschiedlichen Ebenen aus einem Objekt lesen von dem ich weiß, dass es ein mehrdimensionaler Array ist? Allgemeine Java-Themen 3
H Objekt speichern und laden Allgemeine Java-Themen 1
H Objekt speichern und laden Allgemeine Java-Themen 1
J Objekt in Bytestream umwandeln Allgemeine Java-Themen 12
J Wie kann ich von Vornherrein einen Fokus auf ein Objekt entfernen? Allgemeine Java-Themen 3
J Information von getSource() Objekt auslesen Allgemeine Java-Themen 1
Drachenbauer Wie stelle ich fest, ob ein Objekt in meinem Array vorkommt? Allgemeine Java-Themen 5
S Variable als Objekt Name Allgemeine Java-Themen 3
D Input/Output Zwischen zwei ID-Räumen unterscheiden und Objekt löschen Allgemeine Java-Themen 16
L Objekt aus Objekt-array "löschen" Allgemeine Java-Themen 2
T Objekt mit String und Int aus TxT Datei erstellen Allgemeine Java-Themen 23
T Objekt in Array packen Allgemeine Java-Themen 6
K Methodenaufruf mit String / String zu Objekt konvertieren Allgemeine Java-Themen 8
S Neues Objekt darstellen Allgemeine Java-Themen 4
J Best Practice Objekt an alle Klassen verteilen ( Discord Bot ) Allgemeine Java-Themen 7
D Objekt-Suche mit mehreren optionalen Parametern Allgemeine Java-Themen 6
M Klassen Objekt weiter geben Allgemeine Java-Themen 1
B Klassen Objekt erzeugen und Konstruktor aufrufen - Welche Lösung ist besser? Allgemeine Java-Themen 2
L Variablen Eigenes Objekt wie z.B. einen Integer zuweisen Allgemeine Java-Themen 3
D Konstruktor - jedes Objekt einzeln erzeugen - alternative? Allgemeine Java-Themen 8
S Applet Überprüfen ob ein Objekt angeklickt wurde Allgemeine Java-Themen 2
RalleYTN 3D Objekt Translation basierend auf Rotation (Probleme mit Z Rotation) Allgemeine Java-Themen 0
B Von String zu <Objekt> ||Speichern/Laden Allgemeine Java-Themen 17
G Neues Objekt aus List<JsonObject> mit Stream Allgemeine Java-Themen 4
P Threads Objekt im Konstruktor anders wie im Run()-Block Allgemeine Java-Themen 10
R Objekt funktioniert nicht auf iOS Allgemeine Java-Themen 15
K Textdatei als Objekt Allgemeine Java-Themen 4
Viktim Classenname zu Objekt Allgemeine Java-Themen 4
P Entity Objekt Methoden vs Service methoden Allgemeine Java-Themen 2
D Datentypen Klassenattribut aus Objekt in generischer Liste Allgemeine Java-Themen 15
O Klassen Bruch im gleichen Objekt Speichern Allgemeine Java-Themen 1
P Liste zu Objekt umwandeln Allgemeine Java-Themen 4
C Liste checken auf MINDESTENS ein Objekt | Bukkit Allgemeine Java-Themen 3
K Best Practice JFrame Objekt allgemein zugänglich machen Allgemeine Java-Themen 8
B ArrayList in ein Objekt legen Allgemeine Java-Themen 1
D Objekt entlang eines Funktionsgraphens bewegen Allgemeine Java-Themen 6
M Objekt serialisieren/deserialisieren und in einer SQLite-Datenbank speichern Allgemeine Java-Themen 3
D Java Objekt als Service in Runtime registrieren Allgemeine Java-Themen 1
S Interaktion mit einer website (website als Objekt?) Allgemeine Java-Themen 3
J OOP Überwachen, ob ein Objekt erzeugt wird Allgemeine Java-Themen 9
S Byte Array welches in Laufzeit aufgelöst wird // Objekt Array Allgemeine Java-Themen 3
C Generics Objekt in ArrayList Allgemeine Java-Themen 2
L Klassen Konstruktor soll Objekt anderer Klasse erzeugen Allgemeine Java-Themen 2
F Neues Objekt aus .CSV definition Allgemeine Java-Themen 3
K Methoden Objekt wird nicht erkannt Allgemeine Java-Themen 11
P Objekt mit verschiedenen Datentypen Allgemeine Java-Themen 5
T Objekt kontaktiert seinen "erzeuger" Allgemeine Java-Themen 5
S Objekt orientierte Programmierung Allgemeine Java-Themen 7
C Objekt Datenverlust nach Methodenaufruf Allgemeine Java-Themen 9
H JavaFX Von einer Methode auf stage-Objekt zugreifen Allgemeine Java-Themen 3
T WeakReference/PhantomReference: Mitbekommen WELCHES Objekt nun GC'ed wird Allgemeine Java-Themen 2
T Class-Objekt mit URLClassloader Allgemeine Java-Themen 7
P Konsoleneingabe übernehmen und Objekt instanzieren. Allgemeine Java-Themen 5
E Auf Java-Objekt aus anderer Instanz zugreifen Allgemeine Java-Themen 26
L Klassen Polymorphie:2 Attribute gleichen Namens in einem Objekt Allgemeine Java-Themen 6
P Objekt Array in Datei Speichern Allgemeine Java-Themen 3
F Dynamisch ein Objekt einer bestimmten Subklasse erstellen Allgemeine Java-Themen 7
D Player Objekt - Frame über Server anzeigen lassen. Allgemeine Java-Themen 3
V Objekt löschen Allgemeine Java-Themen 7
A OOP Wie auf Objekt der Superklasse zugreifen? Allgemeine Java-Themen 6
S Datei in File-Objekt mit UTF-8 einlesen Allgemeine Java-Themen 2
M neues Objekt speichern, nicht Referenz Allgemeine Java-Themen 10
B synchronisierter zugriff auf Objekt Allgemeine Java-Themen 6
F Objekt einer Datei verschieben, aber Verzeichnispfad fehlt Allgemeine Java-Themen 6
C Objekt Typ herausfinden Allgemeine Java-Themen 5
E Objekt beim Erzeugen in ArrayList Allgemeine Java-Themen 9
M Objekt prüfen auf null ->Invocation Target Exception??? Allgemeine Java-Themen 2
M Objekt aus Liste in Liste suchen/löschen Allgemeine Java-Themen 6
D Eigenen Objekt Pool Allgemeine Java-Themen 15
C blueJ: Objekt wird nicht in Objektleiste angezeigt Allgemeine Java-Themen 8
T Objekt 2x deserialisieren, aber nur 1x im Heap haben? Allgemeine Java-Themen 4
sambalmueslie Benachrichtigung bei neuer Objekt-Instanz Allgemeine Java-Themen 5
U Konstante in Objekt definieren Allgemeine Java-Themen 6
D this mit Objekt überschreiben Allgemeine Java-Themen 17
R Synchronized - auf welchem Objekt Allgemeine Java-Themen 16
E Objekt erstellen Allgemeine Java-Themen 7
M Timer von nicht existiertem Objekt stopen Allgemeine Java-Themen 5
M Swing-Frontend abhängig von ausgewähltem Objekt Allgemeine Java-Themen 4
J Lebt das Objekt noch?? Allgemeine Java-Themen 12
K Objekt einer konkreten Implementierung eines Interfaces durch übergebenen String Allgemeine Java-Themen 2
K Objekt-Austausch zwischen zwei Programmen über System-Clipboard Allgemeine Java-Themen 5
S Performance Frage: Objekt oder static? Allgemeine Java-Themen 33
B Speicherverbrauch Objekt-Referenz Allgemeine Java-Themen 11
D Browser-Objekt erzeugen Allgemeine Java-Themen 8
B FileWriter / FileReader testen / Mock-Objekt für Unit Tests? Allgemeine Java-Themen 6
A Iterationen einer XML-Datei in einem Objekt sichern Allgemeine Java-Themen 5
R Objekt zur Laufzeit zerstören? Allgemeine Java-Themen 12
hdi Frage zur Objekt Initialisierung Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben