Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / January 2008

Tip: Looking for answers? Try searching our database.

serialisation panic

Thread view: 
Roedy Green - 11 Jan 2008 16:19 GMT
I just woke up with some panicky thoughts about serialisation. Some
people dream about women; I dream about Java.

1. If a class does not have a no-arg constructor, how is it possible
for serialisation to reconstitute the object?

2. IIRC constructor initialisation does not happen but what about
STATIC fields?  Do they get initialised?  If so, how?  Does it call
the <clinit> static-initialiser method directly?

3. how does initialisation set the private fields of an object?

Signature

Roedy Green, Canadian Mind Products
The Java Glossary, http://mindprod.com

Thomas Fritsch - 11 Jan 2008 16:33 GMT
Roedy Green schrieb:
> I just woke up with some panicky thoughts about serialisation. Some
> people dream about women; I dream about Java.
Poor man ;-)

> 1. If a class does not have a no-arg constructor, how is it possible
> for serialisation to reconstitute the object?
It is not. See the API doc of Serializable:
<quote>
During deserialization, the fields of non-serializable classes will be
initialized using the public or protected no-arg constructor of the
class. A no-arg constructor must be accessible to the subclass that is
serializable.
</quote>

> 2. IIRC constructor initialisation does not happen but what about
> STATIC fields?  Do they get initialised?  If so, how?  Does it call
> the <clinit> static-initialiser method directly?
I would assume so, since <clinit> is called at class-load-time.

> 3. how does initialisation set the private fields of an object?
I guess it does so by some JNI code in Sun's DLLs. (Remember, JNI has
the power to set any fields, even the private and final ones.)

Signature

Thomas

Zig - 11 Jan 2008 17:09 GMT
> Roedy Green schrieb:
>> I just woke up with some panicky thoughts about serialisation. Some
[quoted text clipped - 9 lines]
> serializable.
> </quote>

True for a class that is non-serializable. Though I think Roedy's question  
was about how Serialization does it under the hood for serializable  
classes?

For those, I assume Serialization is using the JNI function AllocObject:

<quote>
jobject AllocObject(JNIEnv *env, jclass clazz);

Allocates a new Java object without invoking any of the constructors for  
the object. Returns a reference to the object.
</quote>

>>  3. how does initialisation set the private fields of an object?
> I guess it does so by some JNI code in Sun's DLLs. (Remember, JNI has  
> the power to set any fields, even the private and final ones.)

Maybe, but Reflection can do the same I think (if wrapped into a  
AccessController.doPrivileged call).

HTH,

-Zig
Zig - 11 Jan 2008 17:50 GMT
>> Roedy Green schrieb:
>>> I just woke up with some panicky thoughts about serialisation. Some
[quoted text clipped - 22 lines]
> the object. Returns a reference to the object.
> </quote>

Actually, I had to look this up.

From java.io.ObjectStreamClass.newInstance()

Creates a new instance of the represented class.  If the class is  
externalizable, invokes its public no-arg constructor; otherwise, if the  
class is serializable, invokes the no-arg constructor of the first  
non-serializable superclass.  Throws UnsupportedOperationException if this  
class descriptor is not associated with a class, if the associated class  
is non-serializable or if the appropriate no-arg constructor is  
inaccessible/unavailable.

HTH,
Thomas Fritsch - 11 Jan 2008 18:04 GMT
>> Roedy Green schrieb:
>>
[quoted text clipped - 12 lines]
> question  was about how Serialization does it under the hood for
> serializable  classes?
Oops, you're right. I confused non-serializable with serializable.

> For those, I assume Serialization is using the JNI function AllocObject:
>
[quoted text clipped - 4 lines]
> for  the object. Returns a reference to the object.
> </quote>
Sounds very reasonable to me. Actually for classes like Boolean
(implements Serializable, but has no no-arg-constructor) I see no other
way for (de)serialization than JNI-AllocObject.

Signature

Thomas

Mike Schilling - 11 Jan 2008 19:23 GMT
>>> Roedy Green schrieb:
>>>
[quoted text clipped - 28 lines]
> (implements Serializable, but has no no-arg-constructor) I see no
> other way for (de)serialization than JNI-AllocObject.

Can I quibble here?  (De)Serialization is one of the facilities in
Java that require native methods.  (Another is synchronization via
wait()/notify()).  That is, a JVM implementation must implement a way
of creating the object that doesn't involve calling a constructor
immediately thereafter, and make this mechanism available to
readObject().  It's possible that this is the JNI function
AllocObject.  It's also possible that the two both call some
lower-level function.  A third possibility is that the implementations
are wholly unrelated.
Roedy Green - 11 Jan 2008 17:32 GMT
On Fri, 11 Jan 2008 16:33:09 GMT, Thomas Fritsch
<i.dont.like.spam@invalid.com> wrote, quoted or indirectly quoted
someone who said :

>> 1. If a class does not have a no-arg constructor, how is it possible
>> for serialisation to reconstitute the object?
[quoted text clipped - 5 lines]
>serializable.
></quote>

But what about a serialisable class without a no-arg constructor?
Signature

Roedy Green, Canadian Mind Products
The Java Glossary, http://mindprod.com

Roedy Green - 11 Jan 2008 19:34 GMT
On Fri, 11 Jan 2008 16:33:09 GMT, Thomas Fritsch
<i.dont.like.spam@invalid.com> wrote, quoted or indirectly quoted
someone who said :

><quote>
>During deserialization, the fields of non-serializable classes will be
>initialized using the public or protected no-arg constructor of the
>class. A no-arg constructor must be accessible to the subclass that is
>serializable.
></quote>

I am baffled. How could you ever be reconstituting non-serialisable
classes?
Signature

Roedy Green, Canadian Mind Products
The Java Glossary, http://mindprod.com

Owen Jacobson - 11 Jan 2008 21:59 GMT
On Jan 11, 11:34 am, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:
> On Fri, 11 Jan 2008 16:33:09 GMT, Thomas Fritsch
> <i.dont.like.s...@invalid.com> wrote, quoted or indirectly quoted
[quoted text clipped - 9 lines]
> I am baffled. How could you ever be reconstituting non-serialisable
> classes?

Serializable classes can be derived from non-serializable classes.
Trivially, java.lang.Object is not serializable...

When reconstituting a serialized blob into an object, the most-derived
non-serializable class is reconstituted using Java language
mechanisms, which allows it to establish invariants, and then the
remaining data is reconstituted by directly manipulating fields on the
object.

Yes, Serialization cheats on construction.  It's one of the reasons I
don't like it very much. :)

-o
Lew - 12 Jan 2008 00:20 GMT
> Yes, Serialization cheats on construction.  It's one of the reasons I
> don't like it very much. :)

Joshua Bloch covers this extensively in /Effective Java/.  He points out that
making a class implement Serializable is a very, very heavy responsibility.
You create a public interface to the class that subverts access controls, and
lock the (non-transient portion of the) class structure in for eternity if you
wish serialized instances to remain compatible.

No one should use Serializable for non-transitory persistence without reading
those items in /Effective Java/.

Signature

Lew

j1mb0jay - 12 Jan 2008 00:26 GMT
>> Yes, Serialization cheats on construction.  It's one of the reasons I
>> don't like it very much. :)
[quoted text clipped - 8 lines]
> No one should use Serializable for non-transitory persistence without
> reading those items in /Effective Java/.

If i wanted to pass a dataset over a socket how would i do it without
making it 'Serializable' ??

j1mb0jay
Lew - 12 Jan 2008 00:36 GMT
> If i wanted to pass a dataset over a socket how would i do it without
> making it 'Serializable' ??

You can write the values by any number of methods, using ordinary Streams or
Sockets.  Serializable is for persisting objects (and their reference trees),
not data sets.

Some systems use RMI, IIOP or XML to transmit data.

Signature

Lew

j1mb0jay - 12 Jan 2008 00:46 GMT
>> If i wanted to pass a dataset over a socket how would i do it without
>> making it 'Serializable' ??
[quoted text clipped - 4 lines]
>
> Some systems use RMI, IIOP or XML to transmit data.

I use XML else where in my program, is using a Serializable version of a
dataset frowned upon for poor performance ?

j1mb0jay
Lew - 12 Jan 2008 01:45 GMT
> I use XML else where in my program, is using a Serializable version of a
> dataset frowned upon for poor performance ?

It's not the best choice because Serializable has such devastating effects on
the maintenance cost of a class.  Classes contain behavior as well as data.
If all you want to do is persist data, Serializable is waaaay overkill.

Performance is not the issue.  Labor is.  Flexibility is.  Compatibility is.

Performance is far from the most important factor in software.

Signature

Lew

Roedy Green - 12 Jan 2008 06:03 GMT
>I use XML else where in my program, is using a Serializable version of a
>dataset frowned upon for poor performance ?

see http://mindprod.com/jgloss/serialization.html
for the downsides.

The biggest problem is fragility.  If you change any of your classes,
there is a good chance you will never again be able to read your data
files.  It is ROYAL pain to update the format of serialised files. You
need both the old and new formats.  Yet both formats belong to a class
of the same name.

It is for "transient data" where you can afford to just toss your
files and recreate them from scratch or from some sort of formatted
files.

The huge advantage is you can write out a giant complicated tree of
data with one line of code that does not need to be maintained.
Signature

Roedy Green, Canadian Mind Products
The Java Glossary, http://mindprod.com

Zig - 12 Jan 2008 04:42 GMT
>> If i wanted to pass a dataset over a socket how would i do it without  
>> making it 'Serializable' ??
[quoted text clipped - 4 lines]
>
> Some systems use RMI, IIOP or XML to transmit data.

IIRC, to use RMI, one must use Serialization.

From:  
http://java.sun.com/javase/6/docs/platform/rmi/spec/rmi-protocol4.html

<quote>
Call and return data in RMI calls are formatted using the Java Object  
Serialization protocol
</quote>

If I'm not mistaken, when exchanging data through RMI, your values must  
either be primitive, Serializable, or Remote (to which references will be  
replaced by Serializable stubs at transmission time).

That said, at the moment I'm a bit to lazy to write an RMI client & server  
to see what happens when you pass a non-serializable object through...
Lew - 12 Jan 2008 05:37 GMT
> IIRC, to use RMI, one must use Serialization.
>
[quoted text clipped - 13 lines]
> server to see what happens when you pass a non-serializable object
> through...

Good catch, thanks.

It remains that there are many protocols to transmit data or objects.  Since
the OP's question was about data particularly, not object graphs, Serializable
is almost certainly overkill for their needs.  They should use a
lighter-weight and safer protocol.

Signature

Lew

Roedy Green - 12 Jan 2008 06:00 GMT
>You can write the values by any number of methods, using ordinary Streams or
>Sockets.  Serializable is for persisting objects (and their reference trees),
>not data sets.

you can use DataOutputStream directly or use it to create packets you
send in a raw byte stream.
Signature

Roedy Green, Canadian Mind Products
The Java Glossary, http://mindprod.com

Roedy Green - 12 Jan 2008 05:58 GMT
On Fri, 11 Jan 2008 13:59:15 -0800 (PST), Owen Jacobson
<angrybaldguy@gmail.com> wrote, quoted or indirectly quoted someone
who said :

>Yes, Serialization cheats on construction.  It's one of the reasons I
>don't like it very much. :)

Perhaps they should have insisted serialisable classes have a no-arg
constructor, possibly private.

Are there circumstances where fields of non-serialisable superclasses
don't get saved/restored?

.
Signature

Roedy Green, Canadian Mind Products
The Java Glossary, http://mindprod.com

EJP - 13 Jan 2008 23:28 GMT
> Are there circumstances where fields of non-serialisable superclasses
> don't get saved/restored?

There are no circumstances where they *do* get saved/restored. They're
not serializable, so they don't get serialized or deserialized. They get
whatever the default contructor and/or the variable initializers put there.
Lew - 14 Jan 2008 00:12 GMT
>> Are there circumstances where fields of non-serialisable superclasses
>> don't get saved/restored?
>
> There are no circumstances where they *do* get saved/restored. They're
> not serializable, so they don't get serialized or deserialized. They get
> whatever the default contructor and/or the variable initializers put there.

More precisely, what the no-arg constructor put there.

Signature

Lew

EJP - 14 Jan 2008 23:40 GMT
>> whatever the default contructor and/or the variable initializers
>> put there.
>
> More precisely, what the no-arg constructor put there.

More precisely still, the state is the same as if you had invoked the
no-arg constructor, consisting of what super(), the variable
initializers, the instance initialization block {}, and the code in the
no-arg constructor put there.
Lew - 15 Jan 2008 02:15 GMT
>>> whatever the default contructor and/or the variable initializers put
>>> there.
[quoted text clipped - 5 lines]
> initializers, the instance initialization block {}, and the code in the
> no-arg constructor put there.

Somewhat redundant, actually.  All that happens if you invoke the no-arg
constructor, so saying "what the no-arg constructor put there" subsumes the rest.

Signature

Lew

EJP - 28 Jan 2008 07:59 GMT
> Somewhat redundant, actually.  All that happens if you invoke the no-arg
> constructor, so saying "what the no-arg constructor put there" subsumes
> the rest.

Agreed. I was just making the pedantic point that what the no-args
constructor does isn't limited to the code that appears inside it ...
Lew - 12 Jan 2008 00:16 GMT
> Roedy Green schrieb:
>> I just woke up with some panicky thoughts about serialisation. Some
[quoted text clipped - 10 lines]
> serializable.
> </quote>

This says "of non-serializable classes".  It doesn't speak to serializable
classes.

AFAIK there is no problem deserializing an instance of a class that lacks a
no-arg constructor as long as the class implements java.io.Serializable.

>> 2. IIRC constructor initialisation does not happen but what about
>> STATIC fields?  Do they get initialised?  If so, how?  Does it call

Static fields are initialized when the class is loaded, which will have
happened already by the time you're trying to deserialize any instances.

>> the <clinit> static-initialiser method directly?
> I would assume so, since <clinit> is called at class-load-time.

But this has nothing to do with deserialization, of course.

>> 3. how does initialisation set the private fields of an object?

Via the special in-built deserialization mechanism, with possible help from
the readObject() and readResolve() methods.  The deserializer pulls the values
of the private fields from the input stream.

Signature

Lew

Roedy Green - 12 Jan 2008 06:05 GMT
>>> the <clinit> static-initialiser method directly?
>> I would assume so, since <clinit> is called at class-load-time.
>
>But this has nothing to do with deserialization, of course.

It would if the object coming in the wire has never been seen before.
We have the class files on tap, but they have not yet been loaded.
Signature

Roedy Green, Canadian Mind Products
The Java Glossary, http://mindprod.com

Lew - 14 Jan 2008 04:31 GMT
>>>> the <clinit> static-initialiser method directly?
>>> I would assume so, since <clinit> is called at class-load-time.
>> But this has nothing to do with deserialization, of course.
>
> It would if the object coming in the wire has never been seen before.

You mean if its class has never been seen before.

> We have the class files on tap, but they have not yet been loaded.

OK, not "nothing" to do with serialization, but static fields are not
deserialized, they're initialized when the class is loaded, whether because of
serialization or for any other reason.  In that sense the initialization is
not dependent on (de)serialization, which is what I was trying to convey.

The matter of static initialization is orthogonal to serialization, I should
have said.  Since we are picking nits.

Signature

Lew

Roedy Green - 14 Jan 2008 15:15 GMT
>OK, not "nothing" to do with serialization, but static fields are not
>deserialized, they're initialized when the class is loaded, whether because of
>serialization or for any other reason.  In that sense the initialization is
>not dependent on (de)serialization, which is what I was trying to convey.

Normally class loading happens as a side effect of running constructor
or a method.  With serialisation reconstitution, you don't run any
methods. So some special mechanism is necessary to get the class
loaded.

It might call <clinit> or it might use reflection to call some
innocuous method of Object.
Signature

Roedy Green, Canadian Mind Products
The Java Glossary, http://mindprod.com

Lew - 14 Jan 2008 15:25 GMT
>> OK, not "nothing" to do with serialization, but static fields are not
>> deserialized, they're initialized when the class is loaded, whether because of
[quoted text clipped - 8 lines]
> It might call <clinit> or it might use reflection to call some
> innocuous method of Object.

Regardless of why the class loads, initialization of the static members is a
function of class loading, not deserialization.

Signature

Lew

Roedy Green - 14 Jan 2008 16:56 GMT
>Regardless of why the class loads, initialization of the static members is a
>function of class loading, not deserialization.

But then what causes class loading?  Perhaps it does a classForName .
Does that actually force the load?
Signature

Roedy Green, Canadian Mind Products
The Java Glossary, http://mindprod.com

Thomas Fritsch - 14 Jan 2008 18:54 GMT
>>Regardless of why the class loads, initialization of the static members is a
>>function of class loading, not deserialization.
>
> But then what causes class loading?  Perhaps it does a classForName .
> Does that actually force the load?
I'd say yes.

During deserialization the ObjectInputStream somehow converts from class
names (embedded in the byte-stream) to Class objects, AFAIK in method
ObjectInputStream.resolveClass. In this method there is (as you already
guessed) indeed a call to Class.forName

Signature

Thomas

Mike Schilling - 14 Jan 2008 16:47 GMT
>> OK, not "nothing" to do with serialization, but static fields are
>> not
[quoted text clipped - 8 lines]
> or a method.  With serialisation reconstitution, you don't run any
> methods.

Or there's some hidden method, called during deserialization, which
gives you an uninitialized object given the class object,

   Object getUninitializedObject(Class clazz)

The class will be initialized when "clazz" is created, e.g. via
Class.forName()..  No special mechanism required.

> So some special mechanism is necessary to get the class
> loaded.
>
> It might call <clinit> or it might use reflection to call some
> innocuous method of Object.
Rob - 28 Jan 2008 20:06 GMT
I had a good dream about a woman last night. Try it some time.

Rob
http://cbmc64.blogspot.com
Lew - 29 Jan 2008 00:23 GMT
> I had a good dream about a woman last night. Try it some time [sic].
>
> Rob
> http://cbmc64.blogspasm.sputum

PLONK!

Signature

Lew



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.