[Java] serialized hashmap deels leeg na inlezen?

Pagina: 1
Acties:
  • 118 views sinds 30-01-2008
  • Reageer

  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
Ik bouw een HashMap op in mijn programma en die vul ik met sleutels en het daarbij behorende object, deze gebruik ik om een graaf te bouwen en dat gaat allemaal prima. Deze zelfde gebruikte HashMap wil ik vervolgens opslaan in een bestand, deze HashMap zit dus helemaal vol met sleutels+objecten, dat is 100% zeker.

Momenteel ben ik in staat om een HashMap met daarin objecten weg te schrijven. De objecten in de HashMap zijn serializable. Ik sla zo'n 20K objecten op in de HashMap en die HashMap sla ik vervolgens op als een bestand (via een ObjectOutputstream). Allemaal leuk en aardig, ik krijg een bestand en als ik daar met een editor in ga rondkijken zie ik allerlei data - bekende stukjes tekst - er in staan, lijkt dus goed te gaan.

Ik ga vervolgens die opgeslagen Hashmap uit het bestand weer inlezen, dit geeft géén foutmeldingen. Maar wat ik terug krijg is een HashMap met alleen de sleutels, de objecten (values) zitten er wel in alle 20K, maar deze zijn verder leeg.

Help? Ik kan het niet vinden waar het aan ligt of hoe mijn objecten leeg kunnen zijn na inlezen. Het vreemde is ook gewoon dat in het weggeschreven bestand je tussen de binaire data door de informatie terug kunt lezen, het lijkt dus wel opgeslagen te zijn.

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • jAnO!
  • Registratie: Januari 2002
  • Laatst online: 28-01 13:12

jAnO!

lalalavanillevla

hashCode() wel goed geimplementeerd? want anders kan de jvm niet in de bucket kijken waar je object inzit en krijg je null terug.

en equals natuurlijk....

[ Voor 9% gewijzigd door jAnO! op 03-01-2007 14:35 ]

When some people work at a place for ten years they get ten years of experience, other people work at a place for ten years and get one year of experience ten times.


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
Dat zou wel een goeie kunnen zijn, kijken of ik daar iets van kan vinden.

Maar dat eventuele hashCode() probleem zou dan in de objecten moeten zitten die behoren te worden opgeslagen in de HashMap (als waarden) neem ik aan?

[ Voor 88% gewijzigd door Tjeerd op 03-01-2007 14:37 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • jAnO!
  • Registratie: Januari 2002
  • Laatst online: 28-01 13:12

jAnO!

lalalavanillevla

Nestor schreef op woensdag 03 januari 2007 @ 14:35:
Dat zou wel een goeie kunnen zijn, kijken of ik daar iets van kan vinden.

Maar dat eventuele hashCode() probleem zou dan in de objecten moeten zitten die behoren te worden opgeslagen in de HashMap (als waarden) neem ik aan?
inderdaad.

huu... de keys ook natuurlijk...
in ieder geval:
ALTIJD equals en hashCode implementeren!

[ Voor 12% gewijzigd door jAnO! op 03-01-2007 15:10 ]

When some people work at a place for ten years they get ten years of experience, other people work at a place for ten years and get one year of experience ten times.


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 08:22
Het overriden van hashCode() en equals() lijkt mij niet het probleem hier, immers de key objecten zitten wel gewoon in de Hashmap. Voor de value objecten zou het niet uit moeten maken volgens mij, maar ik kan er naast zitten.

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 14:25

Janoz

Moderator Devschuur®

!litemod

Waarschijnlijk zijn de key objecten standaard java objecten en de value objecten eigen gemaakt. Deze laatste objecten zullen waarschijnlijk de hashCode van Object gebruiken. Deze wordt afgeleid van de geheugen locatie. Wanneer je de objecten weer opnieuw inleest zullens ze ergens anders in het geheugen terecht komen. Hierdoor zullen ze een andere hashCode krijgen en daardoor in een andere bucket van de HashMap terecht komen. Hierdoor kunnen ze niet meer terug gevonden worden.

Ik denk dus dat je er naast zit ;).

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
Zoals Janoz al zegt, ik denk dat dat het probleem is. Ik heb inderdaad een HashMap<String, MijnKlasse> gemaakt. Deze sla ik op in een bestand en lees het weer in. Ik doe zelf niets aan het opwekken van hashCodes. Vervolgens zijn de objecten <MijnKlasse> niet meer terug te vinden in de ingelezen HashMap.

Maar, moet ik nu juìst de hashCode zelf implementeren om dit probleem op te lossen?

[ Voor 6% gewijzigd door Tjeerd op 03-01-2007 15:22 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • jAnO!
  • Registratie: Januari 2002
  • Laatst online: 28-01 13:12

jAnO!

lalalavanillevla

hele snelle (niet zo'n goede)

return 1;

When some people work at a place for ten years they get ten years of experience, other people work at a place for ten years and get one year of experience ten times.


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Nestor schreef op woensdag 03 januari 2007 @ 15:22:
Zoals Janoz al zegt, ik denk dat dat het probleem is. Ik heb inderdaad een HashMap<String, MijnKlasse> gemaakt. Deze sla ik op in een bestand en lees het weer in. Ik doe zelf niets aan het opwekken van hashCodes. Vervolgens zijn de objecten <MijnKlasse> niet meer terug te vinden in de ingelezen HashMap.

Maar, moet ik nu juìst de hashCode zelf implementeren om dit probleem op te lossen?
jAnO! schreef op woensdag 03 januari 2007 @ 15:24:
hele snelle (niet zo'n goede)

return 1;
Dat is idd geen goede. :D Maar goed, het werkt wel.

Normaal gesproken is het iig de bedoeling dat je hashcode enigszins andere waarden teruggeeft naarmate je members andere waarden bevatten. Op deze manier komen andere objecten in een ander "emmertje" te zitten en kunnen ze snel gevonden worden. Als je objecten hebt die uit de DB komen, kun je een primary key property returnen in de hashcode.

De enige regel bij hashcodes genereren is dat objecten waarvoor equals true returnt, ofwel gelijkwaardige objecten, de hashcode ook gelijk is. De reden hiervoor is dat het object opgezocht wordt m.b.v. de hashcode...

Lichtelijk overdreven uitleg, maar goed, volgens mij wel duidelijk. :P

Fat Pizza's pizza, they are big and they are cheezy


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 08:22
Janoz schreef op woensdag 03 januari 2007 @ 15:10:
Waarschijnlijk zijn de key objecten standaard java objecten en de value objecten eigen gemaakt. Deze laatste objecten zullen waarschijnlijk de hashCode van Object gebruiken. Deze wordt afgeleid van de geheugen locatie. Wanneer je de objecten weer opnieuw inleest zullens ze ergens anders in het geheugen terecht komen. Hierdoor zullen ze een andere hashCode krijgen en daardoor in een andere bucket van de HashMap terecht komen. Hierdoor kunnen ze niet meer terug gevonden worden.

Ik denk dus dat je er naast zit ;).
Plausibel, maar bij mij in mijn test code werkt het wel zonder hashCode en equals te overriden.
Even snel in elkaar geflanst:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MySerializableObject implements Serializable {

    private static final long serialVersionUID = 1;

    private int intField = 0;

    private String stringField = "";

    public MySerializableObject(int intValue, String stringValue) {
        intField = intValue;
        stringField = stringValue;
    }

    public int getIntValue() {
        return intField;
    }

    public String getStringValue() {
        return stringField;
    }
}


Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class HashMapSerializer {

    private Map<Integer, MySerializableObject> map = new HashMap<Integer, MySerializableObject>();

    private String fileName = "c:/map.ser";

    public static void main(String args[]) {
        HashMapSerializer instance = new HashMapSerializer();
        //instance.fillMap(); 
        //instance.serializeMap();
        //instance.deserializeMap(); 
        //instance.printMap();
    }

    private void fillMap() {
        MySerializableObject obj1 = new MySerializableObject(1, "Object 1");
        MySerializableObject obj2 = new MySerializableObject(2, "Object 2");
        MySerializableObject obj3 = new MySerializableObject(3, "Object 3");
        map.put(1, obj1);
        map.put(2, obj2);
        map.put(3, obj3);
    }

    public void serializeMap() {
        try {
            FileOutputStream fos = new FileOutputStream(fileName);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(map);
        } catch (Exception error) {
            error.printStackTrace();
        }
    }

    public void deserializeMap() {
        try {
            FileInputStream fis = new FileInputStream(fileName);
            ObjectInputStream ois = new ObjectInputStream(fis);
            map = (HashMap<Integer, MySerializableObject>) ois.readObject();
        } catch (Exception error) {
            error.printStackTrace();
        }
    }

    public void printMap() {
        Set<Integer> keySet = map.keySet();
        for (Integer key : keySet) {
            MySerializableObject obj = map.get(key);
            System.out.println(obj.getIntValue() + " - " + obj.getStringValue());
        }
    }
}


Als ik eerst de HashMap vul en daarna serialize, vervolgen deserialize en print werkt dat wel gewoon :?

[ Voor 5% gewijzigd door Kwistnix op 10-01-2007 15:01 ]


  • jAnO!
  • Registratie: Januari 2002
  • Laatst online: 28-01 13:12

jAnO!

lalalavanillevla

FallenAngel666 schreef op woensdag 03 januari 2007 @ 15:44:
[...]


Plausibel, maar bij mij in mijn test code werkt het wel zonder hashCode en equals te overriden.
Even snel in elkaar geflanst:


Als ik eerst de HashMap vul en daarna serialize, vervolgen deserialize en print werkt dat wel gewoon :?
kan, maar vast niet meer als je vult, serialized, jvm opnieuw starten, deserialize en print .

When some people work at a place for ten years they get ten years of experience, other people work at a place for ten years and get one year of experience ten times.


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 08:22
jAnO! schreef op woensdag 03 januari 2007 @ 15:47:
[...]


kan, maar vast niet meer als je vult, serialized, jvm opnieuw starten, deserialize en print .
Als ik eerst allen vul en serialize, dan de applicatie opnieuw start en alleen deserialize en print dan werkt het ook, maar ik bedenk me net dat ik dat vanuit Eclipse doe en dus de JVM niet opnieuw heb gestart...

  • jAnO!
  • Registratie: Januari 2002
  • Laatst online: 28-01 13:12

jAnO!

lalalavanillevla

FallenAngel666 schreef op woensdag 03 januari 2007 @ 15:50:
[...]


Als ik eerst allen vul en serialize, dan de applicatie opnieuw start en alleen deserialize en print dan werkt het ook, maar ik bedenk me net dat ik dat vanuit Eclipse doe en dus de JVM niet opnieuw heb gestart...
toevallig had ik dit probleem tijdje terug met webservices, dus van vm naar vm en dan werkt het *echt* niet..

When some people work at a place for ten years they get ten years of experience, other people work at a place for ten years and get one year of experience ten times.


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 08:22
jAnO! schreef op woensdag 03 januari 2007 @ 15:52:
[...]


toevallig had ik dit probleem tijdje terug met webservices, dus van vm naar vm en dan werkt het *echt* niet..
Hmm, als ik hier de VM kill dan kan ik nog steeds deserializen en correct printen. Ik snap het niet meer.

[ Voor 3% gewijzigd door Kwistnix op 03-01-2007 15:53 ]


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
Ik ben verder gaan zoeken en het probleem is simpeler dan ik zelf ooit had kunnen denken :)

Ik maak gebruik van een open-source package welke geschreven is voor het inlezen van een bepaald soort XML-datastructuur. Fijn, dit was geschreven om in principe alleen die data in te lezen, maar ik wilde met dat pakket een *bijna* zelfde soort XML-datastructuur inlezen. Om het simpel te houden, één veld gebruikte een ander soort sleuteldefinitie (AA:nnnn ipv BB:nnnnn). Dit veld gebruikte ik om later in een HashMap te kunnen zoeken, maar als je een AA-sleutel zoekt in een HashMap met BB-sleutels dan zul je inderdaad niets terugkrijgen natuurlijk.

Omdat het originele bestand wat ik wegscheef een AA-sleutelbestand was, kon ik deze wel leuk inlezen, maar zou ik met een BB-parse-klasse geen enkele sleutel kunnen terugvinden.

Misschien is het nog niet helemaal duidelijk uitgelegd, maar het probleem lijkt dus wel gevonden te zijn, maar toch zeker dank voor de snelle reacties.

[ Voor 3% gewijzigd door Tjeerd op 03-01-2007 15:56 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • D-Raven
  • Registratie: November 2001
  • Laatst online: 16-10 10:47
Even voor de goede orde. Als ik het goed begrijp zit het probleem dus niet in het feit dat je niet de hashCode() methode geimplementeerd hebt. Maar dat je een custom library gebruikt ?..

Het heeft dus niks met 'common practice' voor het serialisen en deserialisen van een hashmap te maken?

Of ben ik t nu helemaal kwijt.. :P

[ Voor 29% gewijzigd door D-Raven op 03-01-2007 16:53 ]


  • martennis
  • Registratie: Juli 2005
  • Laatst online: 27-11 19:57
misschien sluit je de stream naar je file niet goed af?
misschien blijft een deel in de buffer staan..?

probeer je stream eens te flushen en daarna te closen..

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 17:46

Robtimus

me Robtimus no like you

Janoz schreef op woensdag 03 januari 2007 @ 15:10:
Waarschijnlijk zijn de key objecten standaard java objecten en de value objecten eigen gemaakt. Deze laatste objecten zullen waarschijnlijk de hashCode van Object gebruiken. Deze wordt afgeleid van de geheugen locatie. Wanneer je de objecten weer opnieuw inleest zullens ze ergens anders in het geheugen terecht komen. Hierdoor zullen ze een andere hashCode krijgen en daardoor in een andere bucket van de HashMap terecht komen. Hierdoor kunnen ze niet meer terug gevonden worden.

Ik denk dus dat je er naast zit ;).
Volgens mij zit je er flink naast. De hash code wordt gebruikt voor de keys, niet voor de values. De lookup gaat immers per key; er is geen "get" method die een value neemt en daarvoor 1 of meer keys teruggeeft.

Ik heb iets soortgelijks trouwens eens uitgeprobeerd. Ik had keys met variabele hash codes (expres). Eerst objecten geinsert, toen de hash code via via verwijderd, en toen proberen op te zoeken. Dat lukt dus NIET, omdat de hash code en bucket niet meer gelinkt waren. Kijk hier dus goed voor uit als je ooit hash codes variabel maakt.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
@Deathraven: je begrijpt het goed, ik heb zelf niet een eigen hashCode() geimplementeerd en ook de open-source package gebruikt geen eigen hashCode()-implementatie. Maar ik heb iets aangepast waardoor ik twee verschillende formaten kan inlezen en wegschrijven, hierbij heb ik per ongeluk het ene formaat weggeschreven met de ene "reader" en daarna met de andere "reader" het gelezen. Gewoon incompatibilteit wat ik nu kreeg.

Maar het probleem heb ik dus gevonden en ga dat morgen weer oplossen :)

offtopic:
IcemanX: ik ken jouw naam van AK

[ Voor 5% gewijzigd door Tjeerd op 03-01-2007 17:52 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 08:22
IceManX schreef op woensdag 03 januari 2007 @ 17:45:
[...]
Volgens mij zit je er flink naast. De hash code wordt gebruikt voor de keys, niet voor de values. De lookup gaat immers per key; er is geen "get" method die een value neemt en daarvoor 1 of meer keys teruggeeft.
Dat dacht ik dus ook, dus dan is het vrij logisch dat mijn code wel gewoon doet wat ie moet doen.

  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
Hm, vreemd, ik heb mijn eigen object (values die in de HashMap zitten dus) een hashCode()-methode gegeven. Alles verwerkt, dus ik schrijf weer eerst de HashMap<String, EigenObject> weg als een serialized bestand. Dit ga ik vervolgens inlezen en *weer* krijg ik null terug als values. De keys daarentegen zijn er nog *wel* allemaal.

Ik gebruik als sleutel een String()-object en deze zou toch met zijn eigen hashCode()-methode alleen maar unieke waarden moeten genereren? Ze staan er allemaal netjes in de sleutels, dus dat lijkt mij goed te gaan.

Ik vat echt even niet meer waar het probleem zit, ik zit behoorlijk vast :(

[ Voor 13% gewijzigd door Tjeerd op 09-01-2007 15:56 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
Ik heb nog even gekeken en ik krijg wel de klassen terug van type "EigenObject", maar ze zijn deels leeg? Enkele velden hebben hun waarde behouden. Als ik in het weggeschreven serialized bestand kijk zie ik trouwens wel alle informatie er in staan. Het gaat dus fout met het deserializen:
key1, EigenObject // <- value is van het type EigenObject, bevat deels waarden
key2, EigenObject
key3, EigenObject
UPDATE:

De waarden die wel behouden zijn, zitten in EigenObject zelf. EigenObject extends AnderEigenObject. Maar hij lijkt niet de waarden hebben onthouden die in AnderEigenObject zitten opgeslagen. Ik ben weer iets verder dus.

[ Voor 25% gewijzigd door Tjeerd op 10-01-2007 12:00 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 08:22
Nestor schreef op woensdag 10 januari 2007 @ 11:23:
Ik heb nog even gekeken en ik krijg wel de klassen terug van type "EigenObject", maar ze zijn deels leeg? Enkele velden hebben hun waarde behouden. Als ik in het weggeschreven serialized bestand kijk zie ik trouwens wel alle informatie er in staan. Het gaat dus fout met het deserializen:


[...]


UPDATE:

De waarden die wel behouden zijn, zitten in EigenObject zelf. EigenObject extends AnderEigenObject. Maar hij lijkt niet de waarden hebben onthouden die in AnderEigenObject zitten opgeslagen. Ik ben weer iets verder dus.
AnderEigenObject is wel Serializable?

  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
FallenAngel666 schreef op woensdag 10 januari 2007 @ 12:32:
[...]


AnderEigenObject is wel Serializable?
Ik heb dat AnderEigenObject nu ook Serializable gemaakt - vreemd trouwens, ik dacht dat er *altijd* wel een melding zou moeten komen dat een object niet-serializable is - en nu krijg ik een iets groter bestand (15 MB ipv 14 MB). Maar ga ik dat bestand nu inlezen, krijg ik een java.io.EOFException als ik het als ObjectInputStream wil inlezen. Dus ik ben nu daar weer naar aan het kijken.

[ Voor 4% gewijzigd door Tjeerd op 10-01-2007 13:26 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 08:22
Nestor schreef op woensdag 10 januari 2007 @ 13:25:
[...]
Ik heb dat AnderEigenObject nu ook Serializable gemaakt - vreemd trouwens, ik dacht dat er *altijd* wel een melding zou moeten komen dat een object niet-serializable is - en nu krijg ik een iets groter bestand (15 MB ipv 14 MB). Maar ga ik dat bestand nu inlezen, krijg ik een java.io.EOFException als ik het als ObjectInputStream wil inlezen. Dus ik ben nu daar weer naar aan het kijken.
Welke methode van ObjectInputStream gebruik je dan om je geserialiseerde HashMap in te lezen?
De methode readObject() gooit die exception namelijk niet (volgens JavaDoc).

  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
De foutmelding:
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.readFully(ObjectInputStream.java:2648)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1901)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1836)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1713)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1912)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1836)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1713)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:339)
at java.util.HashMap.readObject(HashMap.java:1011)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:919)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1813)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1713)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:339)
at networkbuilder_startree.STExtended.buffer2Object(STExtended.java:793)
Niet zo heel netjes geimplementeerd nog, maar dit is dan de methode:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 public Object buffer2Object(byte[] buffer) {
         ByteArrayInputStream bis = null;
         ObjectInputStream os = null;
         Object o = null;
         
         try {
             System.err.println("buffferlength="+buffer.length);
             bis = new ByteArrayInputStream(buffer);             
             System.err.println("hier");
             
             os = new ObjectInputStream(bis);
             System.err.println("daar");
             o = os.readObject();
             System.err.println("zo");
         } catch (Exception ex) { ex.printStackTrace(); };
    
         return o;
     }

Hij zou eigenlijk opgedeeld moeten worden denk ik, aangezien nu alles in een try is gestopt. Maar bij de laatste methode gaat het dus fout. Ik krijg geen "zo" op mijn console te zien.

Of zou het kunnen dat deze EOFException gelijk al komt omdat de geserializede HashMap in bestandsvorm al niet klopt?

UPDATE:

De klasse <EigenObject> is serializable, dan krijg ik geen EOFException foutmelding, maar verder alleen de keys dus met lege EigenObjecten als values.

Maak ik de klasse <AnderEigenObject> ook serializable - welke dus door <EigenObject> wordt ge-extend - dan krijg ik een EOF-foutmelding.

Mijn probleem lijkt nu trouwens op dit probleem, maar zelfs met een .flush() of .close() erbij blijf ik diezelfde EOF-foutmelding krijgen.

[ Voor 69% gewijzigd door Tjeerd op 10-01-2007 16:44 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Zet er wel alsjeblieft
Java:
1
finally { os.close(); }

achter. :)

bis hoef je niet te closen als je een jdk gebruikt ouder dan 1.4. Dan heeft het geen effect volgens de javadocs. Anders moet die er ook bij.

/Einde-offtopic-modus ;)

Fat Pizza's pizza, they are big and they are cheezy


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
close(), flush(), het maakt niet uit :(

Het wegschrijven lijkt trouwens niet het probleem te zijn - daar krijg ik namelijk geen foutmeldingen- , maar het inlezen van zelf maar een byte gaat al fout:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 public Object buffer2Object(byte[] buffer) {
         ByteArrayInputStream bis = null;
         ObjectInputStream os = null;
         Object o = null;
         
         try {
             System.err.println("buffferlength="+buffer.length);             
             
             bis = new ByteArrayInputStream(buffer);             
             System.err.println("hier="+bis.available()); // geeft 15.613.168 bytes aan
             
             os = new ObjectInputStream(bis);
             System.err.println("daar="+bis.available()); // geeft eveneens 15.613.168 bytes aan
             
             System.err.println("iets="+os.read()); // geeft -1(!) aan (EOF?)
          
             o = os.readObject(); //helemaal kansloos zo ver komt hij niet, geeft ook EOF
             System.err.println("zo");
         } catch (Exception ex) { ex.printStackTrace(); };
    
         return o;
     }

Ik heb het vermoeden dat ik iets simpels over het hoofd zie bij het werken met streams, maar waarom is hij -1 :? Moet ik soms mijn streampointer of iets dergelijks naar het begin zetten?

[ Voor 5% gewijzigd door Tjeerd op 12-01-2007 15:33 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 17:46

Robtimus

me Robtimus no like you

Hoe kom je aan je buffer array? Ik heb even rond zitten spelen, en ik krijg alleen maar EOF exceptions als ik onvolledige byte arrays gebruik.

Sterker nog, de enige manier om deze exception te krijgen (op readFully) is als ik de ObjectInputStream koppel aan een lege InputStream.

[ Voor 33% gewijzigd door Robtimus op 12-01-2007 17:06 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
IceManX schreef op vrijdag 12 januari 2007 @ 17:05:
Hoe kom je aan je buffer array? Ik heb even rond zitten spelen, en ik krijg alleen maar EOF exceptions als ik onvolledige byte arrays gebruik.

Sterker nog, de enige manier om deze exception te krijgen (op readFully) is als ik de ObjectInputStream koppel aan een lege InputStream.
De buffer-array wordt gevuld vanuit een URL-stream, deze is helemaal gevuld. Ik heb namelijk een methode die deze buffer-array wegschrijft naar een bestand en als ik die dan vergelijk met het "originele" serializde hashmap-bestand dan zijn die identiek.

Maar wat bedoel je met "onvolledige arrays"?

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 17:46

Robtimus

me Robtimus no like you

Arrays die het begin of het einde van de object-als-bytes missen. Als test had ik bv een object geserialized, dat array op het eerste element na naar een ander array gekopieerd, en toen terug gedeserialized. Resultaat: EOFException.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
Hij wordt nu echt *helemaal* mooi :D, twee manieren om een object naar een bestand weg te schrijven en ze verschillen uiteindelijk ongeveer 8 kilobyte in grootte.

Ik heb twee methodes gebruikt om een HashMap weg te schrijven. De één levert een bestand op van 15.613.168 bytes:
Java:
1
2
3
4
5
6
7
8
9
10
11
  
        try {
          fos = new FileOutputStream(theFile);
        } catch (Exception e) { e.printStackTrace(); }
        
        try {
          oos = new ObjectOutputStream(fos);
          oos.writeObject(theGOmap); //==hashmap met 22K geserializeerde objecten
          oos.close();       
          fos.close();
        } catch (Exception e) { e.printStackTrace(); } 


De andere methode levert een bestand op van 15.605.741 bytes:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
ObjectOutput output = null;
        
        try {
            OutputStream file = new FileOutputStream( theFile );
            OutputStream buffer = new BufferedOutputStream( file );
            output = new ObjectOutputStream( buffer );
            output.writeObject(theGOmap); // zelfde HashMap als in andere methode
            output.flush();
            file.close();
            buffer.close();
            
        }
        catch (Exception ex) { ex.printStackTrace(); }

Hoe in vredesnaam is dit mogelijk? Het lijkt er dus op dat met het schrijven iets al verkeerd gaat, wat misschien de EOF verklaart. Hoe kan het dat een gebufferde manier van schrijven in dit geval een kleiner bestand oplevert dan via een "gewone" filestream?

Om bovenstaande te testen comment ik gewoon één van beide manieren van schrijven, verder verander ik *niets* aan de overige code.

[ Voor 11% gewijzigd door Tjeerd op 15-01-2007 10:18 ]

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
Allememachies! dit is echt ongelofelijk, ik heb de oorzaak gevonden van dit probleem.

Het blijkt een Java heapspace probleem te zijn, ik heb *nooit* eenmelding gekregen dat ik te weinig geheugen had. Nou schoot er daarnet wel ineens een foutmelding langs "OutOfMemoryError" (gelukkig).

Toen begon me iets te dagen, zou het parsen van het originele bestand en het opbouwen van de HashMap in het geheugen misschien daar last van hebben? De heapspace-limiet verhoogd naar 512 MB en verdomme, het werkt! :D

Krijg nu een bestand van ongeveer 17 MB en hij schrijft goed weg en leest ook goed in.

Fijn, dit soort dingen houdt je echt heel lang bezig en maakt je gefrustreerd. Het rare blijft dat ik nooit eerder die OutOfMemoryError voorbij heb zien komen.

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 08:22
Welke resultaten krijg je als je de applicatie met HPROF profileert?

  • Tjeerd
  • Registratie: Oktober 1999
  • Laatst online: 15:40

Tjeerd

Be Original, Be Yourself.

Topicstarter
Erg onduidelijke resultaten, heb 'm even laten draaien:
java -Xms512m -Xmx512m -agentlib:hprof=heap=sites mijnproggie xml-invoerbestand
Die blijft minuten lang draaien en moet 'm met Ctrl-Break stoppen en dan krijg ik een dump met hoeveel % geheugen bijvoorbeeld verschillende objecten gebruiken. Vreemde is dat hij door blijft draaien en dat als ik 'm dus afbreek hij honderden MB's lijkt te gebruiken.

Draai ik 'm daarentegen zonder extra parameters en ik kijk in mijn Taak Beheerder dan zie ik dat het geheugengebruik begint bij 40 MB en zo rond de 95 MB op z'n piek is. Daarna is het programma klaar. Dat ziet er uit als realistische waarden. De standaard 64 MB limiet van programma's heeft denk ik een rol gespeeld (onzichtbaar). Maar nu werkt het dus probleemloos en gebruikt het ook niet veel geheugen.

www.tjeerd.net - To repeat what others have said, requires education, to challenge it, requires brains.

Pagina: 1