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 / First Aid / May 2005

Tip: Looking for answers? Try searching our database.

ClassCastException when it should work anyway

Thread view: 
Jimi Hullegård - 28 May 2005 20:56 GMT
Is there a way to avoid a ClassCastException when there is no real changes
made to the class, but the java-file has been compiled anyway?

I'm writing a J2ee web application, and I store a HashMap of User objects as
an attribute in the servlet context. Now, if the User class gets recompiled
(no changes has been made in the code), I get a ClassCastException when I
try to fetch an User from the HashMap.

Code:
Map<Integer, User> onlineUsers = (Map<Integer,
User>)servletContext.getAttribute("onlineUsers");
User user = onlineUsers.get(new Integer(memberId)); <--- this throws a
ClassCastException

But if I don't do "User user = ..." and just prints the object returned, the
it clearly IS a User object, because printout is something like
community.login.User@861f24

So is there a way to "Cast" an object between two classes that actually are
the SAME class, but different versions (I guess)?

/Jimi
Chris Smith - 28 May 2005 21:08 GMT
> I'm writing a J2ee web application, and I store a HashMap of User objects as
> an attribute in the servlet context. Now, if the User class gets recompiled
[quoted text clipped - 13 lines]
> So is there a way to "Cast" an object between two classes that actually are
> the SAME class, but different versions (I guess)?

Short answer: no.

A class in Java is identified by two pieces of information, a fully
qualified class name and a class loader.  Each class loader effectively
defines its own class namespace, so that even if two classes have
exactly the same fully qualified name ("community.login.User") for
example, if they were loaded by different class loaders then they are
still not the same.

Since a class of the given name has already been loaded by your servlet
container, I suppose it's deciding to create a new class loader to load
the new class.  I think that's a very poor idea, but unless you switch
servlet containers there isn't anything you can do about it.  (An
alternative which is implemented by other containers is to actually
serialize all the session and application-scope state out to a file,
reload the entire application, and read it back in.  Tomcat can do that,
for example.)

Is changing servlet containers an option?  What container are you using
now?

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Jimi Hullegård - 28 May 2005 23:32 GMT
> Short answer: no.
>
[quoted text clipped - 5 lines]
> example, if they were loaded by different class loaders then they are
> still not the same.

Thank your for that clear and straight answer. I think I understand now.

> Is changing servlet containers an option?  What container are you
> using now?

I'm using Orion (www.orionserver.com). And though changing servlet container
is possible, I would prefer not to have to go thr through that hassle.

But I'm starting to think that I should focus on the main problem, and maybe
you can help me with that?
Because the thing is, I'm having problems registering logouts on a community
I'm building (a test site, at the moment). Everything works when the logged
in user clicks on logout, and when when a regular time out happens. But if I
for instance recompile the servlet when orion is running, or make some
changes in some xml-file, then then _some_ users get logged out completely
(which is OK), while others not get logged out completely (logout time not
written to the database).
So I would like to write a function that runs every five minutes (or
whatever) and goes thrue all active sessions, retrieves the corresponding
user object, and compares the the ones who is logged in according to the
database.
But the thing is I can't find any way to get hold of all active sessions. I
have looked everywhere... Any ideas?

Regards
/Jimi
Ross Bamford - 29 May 2005 12:03 GMT
On Sun, 2005-05-29 at 00:32 +0200, Jimi Hulleg=A5rd wrote:
> > Short answer: no.
> >
[quoted text clipped - 29 lines]
> But the thing is I can't find any way to get hold of all active sessions. I
> have looked everywhere... Any ideas?

You're confusing your container with running changes. Do this with a
development machine in particular circumstances *if you must* but not
ever with a production machine.

Imagine you write a program that includes all kinds of complex class
manipulation stuff to make sure that the right classes are available at
the right time. You have multiple boxes for your classes, and use clever
stuff like lazy init and bytecode caching. It'll all work transparently,
since the bytecode will be the same no matter which box loads it,
right?

Until someone changes the bytecode after the caches have started to fill
up.

Signature

  [Ross A. Bamford]     [ross AT the.website.domain]
Roscopeco Open Tech ++ Open Source + Java + Apache + CMF
http://www.roscopec0.f9.co.uk/ + info@the.website.domain

Jimi Hullegård - 30 May 2005 14:47 GMT
>>> Short answer: no.
>>>
[quoted text clipped - 47 lines]
> Until someone changes the bytecode after the caches have started to
> fill up.

Well, I have already solved the main problem, without manipulating with
class loaders or bytecodes. I now keep track of all active sessions (using a
session listener), and I have written a "tidy up" function that fixes any
incomplete logouts.

/Jimi
daleerwin@infonegocio.net.pe - 29 May 2005 02:58 GMT
I'm not really sure, but I had a similar situation with a J2SE
application, and I'll tell you what happened:

I was putting ScoreObject objects on a Vector from two different
locations.  In one place the instances were built from data entered by
the user and in the other place they were built from data fread from a
database.  Then the paintComponent() method used this Vector to repaint
the screen.  When the paintComponent() method read the Vector, the
objects built from user-data had no problem, but the objects built from
database data began to throw this exception and did it consistently
thereafter.

I tried lots of things, but finally I first tested the object on the
Vector with the "instanceof" keyword for that class and if it returned
true, then I did the Cast.  All of the objects now get drawn, and it
hasn't thrown that exception since.

YMMV


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



©2008 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.