Hello Everyone,
I'm currently working on a Plugin that simplifies evaluation of microbiological images. Therefor I planned to develop a serializable object, such that I can save and load my results in an easy way. I understand that I can only use fields that are serializable as well, but somehow I still receive a NotSerializableException: java.io.NotSerializableException: sun.java2d.SunGraphics2D at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeArray(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.access$300(Unknown Source) at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source) at java.io.ObjectOutputStream.writeFields(Unknown Source) at java.awt.Container.writeObject(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeObject(Unknown Source) at java.awt.AWTEventMulticaster.save(Unknown Source) at java.awt.Component.writeObject(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeObject(Unknown Source) ... Here is my source code: import ...; public class EvaSer implements Serializable{ /** * */ private static final long serialVersionUID = 3873721584911475388L; /** * */ /** * */ public int nSpec; public int nImages; public List<int[][]> types; public String evalName; public String[] specNames; public String[] typeNames; public List<String> imageNames; // For every Image one List element public List<Roi[][]> rois; // For every Image one Roi[nSpec][] public List<Roi> fixpoints; // Every Image one Fixpoint public List<File[]> files; // Original and Evaluated Files public Roi[] ovrls; // Control Ovrls from Flourescence as Roi[nSpec] public Color[] specieColors; // Chosen Colors for Species Color[nSpec] public File dir; // Directory of "Evaluated" ... public EvaSer(){ this.evalName="new Evaluation "+System.currentTimeMillis(); initLists(); initTypeArrs(); } private void initTypeArrs() { typeNames=new String[]{""}; } public void initLists() { this.imageNames= new ArrayList<String>(); this.rois= new ArrayList<Roi[][]>(); this.fixpoints= new ArrayList<Roi>(); this.files= new ArrayList<File[]>(); //files[0]= origin; files[1]= evaluated; this.types= new ArrayList<int[][]>(); } public void save(Component parent) { System.out.println(this.nSpec); System.out.println(this.nImages); System.out.println(this.types.toString()); System.out.println(this.evalName); System.out.println(this.specNames.toString()); System.out.println(this.typeNames.toString()); System.out.println(this.imageNames.toString()); System.out.println(this.rois.toString()); System.out.println(this.fixpoints.toString()); System.out.println(this.files.toString()); System.out.println(this.ovrls.toString()); System.out.println(this.specieColors.toString()); System.out.println(this.dir); String path; path=this.dir.toString(); if(this.evalName==null){ this.evalName=RegularFunctions.getName(parent); } path=path+this.evalName+".eva"; ObjectOutputStream oos = null; FileOutputStream fos = null; try { fos = new FileOutputStream(path); oos = new ObjectOutputStream(fos); oos.writeObject(this); } catch (IOException e) { e.printStackTrace(); } finally { if (oos != null) try { oos.close(); } catch (IOException e) { } if (fos != null) try { fos.close(); } catch (IOException e) { } } } public EvaSer load(String path) { ObjectInputStream ois = null; FileInputStream fis = null; Object so= new Object(); try { fis = new FileInputStream(path); ois = new ObjectInputStream(fis); Object obj = ois.readObject(); if (obj instanceof EvaSer) { so = (EvaSer) obj; } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (ois != null) try { ois.close(); } catch (IOException e) { } if (fis != null) try { fis.close(); } catch (IOException e) { } } return (EvaSer) so; } } Thanks to all of you who's time I'm stealing ;) |
Hi Influenza,
On Sun, 11 May 2014, Influenza wrote: > I'm currently working on a Plugin that simplifies evaluation of > microbiological images. Therefor I planned to develop a serializable object, > such that I can save and load my results in an easy way. Please study what Java serialization is, exactly. I fear that the way you are using is outside its intended usage. In particular, you will find that trying to serialize random objects whose classes define all kinds of fields intended for display will cause all kinds of problems that you will only understand if you know what serialization is about. There is a good reason, for example, why ROIs in ImageJ are saved in a custom format rather than using Java serialization. The same applies, most likely, to your data: you want to be specific about what to write to disk, and avoid using Java serialization (which backfired rather nicely in your case, too ;-)). Ciao, Johannes -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi,
> Please study what Java serialization is, exactly. I fear that the way > you are using is outside its intended usage. In particular, you will > find that trying to serialize random objects whose classes define all > kinds of fields intended for display will cause all kinds of problems > that you will only understand if you know what serialization is about. Perhaps the Externalizable interface would be a better fit here: http://stackoverflow.com/q/817853 Externalization gives you more complete control over the process. It is initially more work but much more robust long term. Regards, Curtis On Mon, May 12, 2014 at 3:39 PM, Johannes Schindelin < [hidden email]> wrote: > Hi Influenza, > > On Sun, 11 May 2014, Influenza wrote: > > > I'm currently working on a Plugin that simplifies evaluation of > > microbiological images. Therefor I planned to develop a serializable > object, > > such that I can save and load my results in an easy way. > > Please study what Java serialization is, exactly. I fear that the way you > are using is outside its intended usage. In particular, you will find that > trying to serialize random objects whose classes define all kinds of > fields intended for display will cause all kinds of problems that you will > only understand if you know what serialization is about. > > There is a good reason, for example, why ROIs in ImageJ are saved in a > custom format rather than using Java serialization. > > The same applies, most likely, to your data: you want to be specific about > what to write to disk, and avoid using Java serialization (which backfired > rather nicely in your case, too ;-)). > > Ciao, > Johannes > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by dscho
Hi steve,
On Tue, 13 May 2014, Steven Görlich wrote: > i really thought, I'd studied serialized objects well, but it seems that I > was wrong. I spend attention on the fields being serializable as well.... > Curiously, it used to work until a certain point, with almost all the > fields that are implemented by now. Sorry, my comment was misleading: I am sure that you studied the details of the Java serialization well. However, I think that there might be a slight misconception what Java serialization is intended for. It is distinctly *not* intended for storage. Java serialization is substantially too fragile for that: the binary protocol depends on the implementation details. For example, you simply cannot deserialize Java objects with Android that were serialized with OpenJDK, because the specs allow explicitly to override the binary protocol by implementing the writeObject/readObject methods. When using a class path library that implements those methods differently (or one of both implementations does *not* implement them), you're out of luck. A good example is the TreeMap class if you want to learn more. What serialization *is* intended for is to be able to page out data e.g. when RAM becomes scarce, and to be able to page things back in later, when needed. To that end, Java serialization defaults to serialize all fields recursively, no matter whether that is proper or not (it is very easy to see that an open file handle simply cannot serialized properly). Your case hits one of these limitations: the Roi class has a reference to the ImageCanvas which is a *GUI* element. As such, you probably never want to serialize it because it is bound to an *actual window*. You simply cannot deserialize such things robustly because the window might not even exist! BTW please do not be mislead by the fact that ij.gui.Roi is marked Serializable, it is not well tested (the ImageCanvas field I mentioned above clearly would need to be marked as "transient" for example) and it distinctly does not work, unless you drive it in a very narrow manner. Even apart from that, it is not intended for storage. > You mentioned that Rois are saved in a custom way? Such a question is really asked much better on the mailing list than in a private mail (you really do not want to treat me as a commodity private help desk, right?). It is your lucky day that I have enough time to answer. In any case, to maximize the effect of my answer (you are certainly not the only one who can benefit from my expertise), I Cc:ed the mailing list. When you call File>Save As>Selection..., the real work is done by the ij.io.RoiEncoder class. You might want to read up on the documentation of that class: http://jenkins.imagej.net/job/ImageJ1-javadoc/javadoc/ij/io/RoiEncoder.html Ciao, Johannes -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |