| Author |
How do Singleton class? Is it even possible?
|
Robert Paris
Ranch Hand
Joined: Jul 28, 2002
Posts: 585
|
|
I know this seems like a beginner question, but hear me out. Frequently, I see implementations for singleton classes, as such: And for the most part this is a singleton. However, what if I decide I want my Singleton to be a Singleton in the entire JVM? The above doesn't work. Imagine the following scenario: I'd say we just destroyed the singleton. And this may get even more troublesome when we move to multiple JVMs, but for now I'll stick to this. Is there a way to enforce Singletons in a single JVM without forcing the singleton to be loaded by the system classloader? (And even then, you could still do it if you made a "bad" classloader that didn't check with its parent for defining classes) [ February 10, 2003: Message edited by: Robert Paris ] [ February 10, 2003: Message edited by: Robert Paris ]
|
 |
Steve Luke
Bartender
Joined: Jan 28, 2003
Posts: 1900
|
|
I am no expert, so I may be wrong, but I don't think the Class.forName acually creates an instance of the class. You would have to use clzz.newInstance() to actually make the instance of the class. This would fail, however, with an IllegalAccessException because the null-listed constructor is not accessable. Least, thats what I think would happen... Steve
|
Steve
|
 |
Peter den Haan
author
Ranch Hand
Joined: Apr 20, 2000
Posts: 3252
|
|
If it's a web container context, I'd suggest to store singletons as ServletContext attributes rather than static fields. Beware of ClassCastExceptions though -- if your Singleton class gets reloaded, the object stored in the ServletContext will no longer be instanceof Singleton. You see what it boils down to -- if you can store your singleton in a class that will never get reloaded, you're done. Except for the ClassCastExceptions of course. - Peter
|
 |
Steve Luke
Bartender
Joined: Jan 28, 2003
Posts: 1900
|
|
//THEN USE BOTH clazz AND clzz2 TO MAKE NEW INSTANCES Woops, missed that part of the code. So you would do like clzz.getNewInstance() (or whatever it was) and clzz2.getNewInstance() I guess that is different. Would a static variable work across these two seperate Class objects as clzz2 won't be initialized (since it would have been with clzz already)? If so, you could use a static boolean to check if it was already loaded, and if so just return refernce to old instance...
|
 |
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18652
|
|
Using reflection allows you to circument access modifiers anyway, even without reloading a class using different class loaders. Try this: You can create two instances of a singleton this way thanks to the setAccess(true) method. Normally we don't worry about this - access modifiers are designed to protect you from accidental misuse of code by people invoking methods/constructors/fields normally. If someone really wants to intentionally screw up the program using reflection, they can - unless you set the suppressAccessChecks permission to false so that the SecurityManager will throw a SecurityException when the setAccess() method is attempted. (This is what happens by default if you're running an Applet for example.) You can also enforce a singleton more aggressively by replacing the constructor with something like this: Setting appropriate security permissions is probably the more "proper" way to deal with this issue if you need to though. Incidentally if a class is Serializable that creates another loophole which allows two different Singleton instances to be created (by deserializing the saved bytes twice). This loophole is not blocked by my RuntimeException above; desrialization does not actually invoke constructors to make an object. ( !) You can fix this by adding a readResolve() method: This method is called as part of the deserialization process - it allows you to replace the second instance which the deserializer was in the process of constructing, with another (namely, the one instance you want in this case). Read up on serialization for more details. [ February 10, 2003: Message edited by: Jim Yingst ]
|
"I'm not back." - Bill Harding, Twister
|
 |
Robert Paris
Ranch Hand
Joined: Jul 28, 2002
Posts: 585
|
|
Jim, Thanks for that great reply! Yeah, I had forgotten to mention the deserialization (it's included in RMI anyways, which I mentioned as two diff. JVMs). But you didn't really answer how i stop the two diff. classloaders problem. I'll wait on your answer on that, but until then, I'd assume that the following does what I need (from what you said): The final part is: So now, as far as i can see, we've ensured that everything using the same classloader sees just one instance of this class. What about the multiple clasloaders problem?
|
 |
Frank Carver
Sheriff
Joined: Jan 07, 1999
Posts: 6913
|
|
Patient: "Doctor, It hurts when I do *this* !" Doctor: "Well, don't do *this*" Or, in programming terms: If you are having such trouble making a Singleton proof agains all these possibilites, maybe you shouldn't be using a Singleton at all. Can you give us a more concrete example of what you want to use such a Singleton for? Maybe we can suggest a way which doesn't involve all this trickiness and thus is not such a nursery for bugs.
|
A Convergent Visionary ~ Frank's Punchbarrel Blog ~ LinkedIn profile
|
 |
Robert Paris
Ranch Hand
Joined: Jul 28, 2002
Posts: 585
|
|
Patient: "Doctor, It hurts when I do *this* !" Doctor: "Well, don't do *this*"
I never said it was hurting me! Well, I have an application and it has a configuration manager. now there are a few issues here: 1. I allow hot deployment (to do this, I have to load with new classloaders and return the new class which of course implements the interface they're programming to) 2. i allow other people's components (the inner code of which i have no control over) in my system. So there are two areas in which i want to be certain my singleton (the configuration manager, which since it doles out config info and such is also closely tied to the application's security settings) is a singleton: 1. I don't want to accidentally create two instances (through the classloader structure) 2. i don't want users or their code to be able to create a different instance of this config manager Any ideas?
|
 |
 |
|
|
subject: How do Singleton class? Is it even possible?
|
|
|