Problems retrieving object through rmi

S

steen

Hey,

I've just started a job at a company maintaining their existing
applications.
They have a swing application which retrieves an object through rmi
and this is where I've run into a problem.

If I run the client code through Eclipse I get a
Caused by: java.rmi.UnmarshalException: Error deserializing return-
value: java.io.InvalidClassException:
dk.company.core.shared.security.User; local class incompatible: stream
classdesc serialVersionUID = 9118414514559389810, local class
serialVersionUID = 5591922392715427412

but if I run it through IDEA it works just fine.

I'm thinking there is a problem with the java versions, but as far as
I can see both eclipse and idea run with the same settings :
Eclipse: jdk1.6.0_01 as compiler and 1.4 as "Generated .class files
compatibility" and "Source compatibility"
IDEA: same jdk1.6.0_01 as compiler and 1.4 as "Project language level"

I'd prefer to use Eclipse for this but if I cant resolve this I guess
I'll have to go with IDEA.

Anyone got any ideas what setting in Ecilpse I'm missing ?

/Steen
 
R

Roedy Green

If I run the client code through Eclipse I get a
Caused by: java.rmi.UnmarshalException: Error deserializing return-
value: java.io.InvalidClassException:
dk.company.core.shared.security.User; local class incompatible: stream
classdesc serialVersionUID = 9118414514559389810, local class
serialVersionUID = 5591922392715427412

The class files don't match. Makes sure the source is identical then
Try a rebuild of the universe. You may just have some old class
files. Make sure both Idea and Eclipse are pointing to the same
version of the RMI libraries.
 
S

steen

The class files don't match. Makes sure the source is identical then
Try a rebuild of the universe. You may just have some old class
files. Make sure both Idea and Eclipse are pointing to the same
version of the RMI libraries.

I've dug around a bit and noticed that there was a slight difference
in the class files for the object
I'm trying to transfer, so if I on the server put the class file
compiled by Eclipse it works,
but why is there such a change? The jar-file for the server part was
built using ant through Eclipse.
I have a vague memory of someone telling me that Eclipse used its own
compiler and not the default javac
is this so? If so, is it possible to make Eclipse use the same javac
as my ant build script does ?
(I'm guessing here that compiling the same class twice with the same
compiler would produce identical class-files)

/Steen
 
M

Mark Thornton

steen said:
I've dug around a bit and noticed that there was a slight difference
in the class files for the object
I'm trying to transfer, so if I on the server put the class file
compiled by Eclipse it works,
but why is there such a change? The jar-file for the server part was
built using ant through Eclipse.
I have a vague memory of someone telling me that Eclipse used its own
compiler and not the default javac
is this so? If so, is it possible to make Eclipse use the same javac
as my ant build script does ?
(I'm guessing here that compiling the same class twice with the same
compiler would produce identical class-files)

/Steen

Make sure that all the classes being serialised specify an explicit
serialVersionUID, then it won't matter which compiler is used.

Mark Thornton
 
S

steen

Make sure that all the classes being serialised specify an explicit
serialVersionUID, then it won't matter which compiler is used.

Ah, of course. *slaps himself for not thinking of that!*
I'm gonna try that monday morning, thanks..:)

/Steen
 
N

Nigel Wade

steen said:
Ah, of course. *slaps himself for not thinking of that!*
I'm gonna try that monday morning, thanks..:)

/Steen

But don't forget that you are now responsible for maintaining the UID. If you
change the class in any meaningful way (such that the data which is serialized
will be different) then you should update the serialVersionUID. The prevents a
class with one UID attempting to de-serialize objects with a different UID, and
hence incompatible contents.
 
E

Esmond Pitt

Nigel said:
But don't forget that you are now responsible for maintaining the UID. If you
change the class in any meaningful way (such that the data which is serialized
will be different) then you should update the serialVersionUID. The prevents a
class with one UID attempting to de-serialize objects with a different UID, and
hence incompatible contents.

No no no. That will break your downward compatilibity. Serialization
already supports versioning to a great extent. As long as you stay
within the rules there is no need to change the serialVersionUID at all
and it is a practice to be actively discourage. The applicable rules are
defined in the Serialization Specification but they amount basically to
not deleting fields, not changing inheritance, and not change the types
of fields. There's an awful lot you can accomplish within those limits.
If you have to go outside them you should then use one of the available
serialization mechanisms to render the new class
serialization-compatible with the old one, and there is an awful lot
more you can do within these mechanisms.

If you *want* to break backwards compatibility, and lose contact forever
with any persistent serializations you may have done, then change the
serialVersionUID. Not otherwise.
 
N

Nigel Wade

Esmond said:
No no no. That will break your downward compatilibity.

Yes, yes, yes. If you break the backwards compatibility then you must change the
UID, or face the consequences.
Serialization
already supports versioning to a great extent. As long as you stay
within the rules there is no need to change the serialVersionUID at all
and it is a practice to be actively discourage. The applicable rules are
defined in the Serialization Specification but they amount basically to
not deleting fields, not changing inheritance, and not change the types
of fields. There's an awful lot you can accomplish within those limits.
If you have to go outside them you should then use one of the available
serialization mechanisms to render the new class
serialization-compatible with the old one, and there is an awful lot
more you can do within these mechanisms.

What I said was that if you change the contents of the serialized object then
you must manually alter the UID. That remains valid no matter how many rules
and tools you use to try to circumvent it.
If you *want* to break backwards compatibility, and lose contact forever
with any persistent serializations you may have done, then change the
serialVersionUID. Not otherwise.

Like I said...
 
E

Esmond Pitt

Nigel said:
Yes, yes, yes. If you break the backwards compatibility then you must change the
UID, or face the consequences.

But if you don't, don't. And please read the Serialization/Versioning
spec carefully before you decide that you have broken backwards
compatibility. Better still, design so that you don't ever do this.
What I said was that if you change the contents of the serialized object then
you must manually alter the UID.

And this is still not correct. See the Serialization/Versioning spec, or
my hasty summary of it. You can change a serializable class in lots of
ways without breaking serialization-compatibility. In a practical
production system it behoves you to keep compatibility in mind at all
times, and to have an *accurate* view of what that actually means in
practice. This means reading the Serialization specification, the
section on Versioning, no two ways about it.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top