Singleton pattern, multiple instances?
I was recently asked the following trivia concerning the Singleton Pattern:
The following class implements the Singleton pattern. The basic idea is to ensure that there will only exist ONE instance of the Dog class.
publicclass Dog{
publicstaticfinal Dog INSTANCE =new Dog();
private Dog(){}
@Override
public String toString(){
return"Gua Gua!";
}
}
However, it is posible in Java to create a second instance from another class. Write the code that may accomplish this.
There's also another condition: the use ofreflection is not allowed, so that it's not possible anymore to use something like this:
Dog d = (Dog)java.security.AccessController.doPrivileged(
new PrivilegedAction()
and then:
Constructor cons= Dog.class.getDeclaredConstructor();
cons.setAccessible(true);
return cons.newInstance(null);
I have read a lot about the drawbacks of the Singleton pattern and most of them consist on Thread issues (which I think by declaring as a class variable the unique INSTANCE and by avoiding the typicalgetInstance() method are discarded) and Class loading.
Any help with this challenge?
[1858 byte] By [
cobi3000a] at [2007-10-2 3:56:19]

> I was recently asked the following trivia concerning> the Singleton Pattern:"I was recently given a homework problem concerning the Singleton Pattern:"Look at serialization.
Very easy, override the readResolve() method and make the class Serializable.
If your Singleton is read-only, then thread safety is not an issue. Singletons (and caching strategies) are best when used on read-only or read-mostly data. This is because they behave as a proxy for global variables. Synchronizing the methods is an option, but in a multi-threaded environment, this could lead to a scaling bottleneck.
I do not see the issue with using getInstance(). Assuming there is not a race condition where null is being checked (e.g., initializing the instance as was done in your case or via a static initializer). Class loading should not be an issue either. Garbage collection might be, but I do not see how class loading would be any different. Though I may be wrong on that one.
- Saish
Saisha at 2007-7-15 23:17:40 >

I didn't know the serialize one.1. Do it via JNI.2. Do it with two class loader instances.Did it mention that it has to be in the same VM? If not then just run two VMs.
Of course one could also mention that the whole point of a singleton is that there is one and so if someone wants more than one then they should change the design rather than trying to find code loop holes around it.Perhaps a multiton would work.
> Very easy, override the readResolve() method and make
> the class Serializable.
Thanks for your interest in this topic. Of course, serialization is one possibility but, unfortunately, it is not possible to modify in any way the original Dog class.
I know that this "trivia" may not represent an issue that has to do with the correct use of the Singleton pattern in practice, but it has to do with the theoretical and possible drawbacks that may occur in Java.
> I didn't know the serialize one.
>
> 1. Do it via JNI.
> 2. Do it with two class loader instances.
>
> Did it mention that it has to be in the same VM? If
> not then just run two VMs.
I think I may have demonstrated the possibility of using two class loaders, but I haven't been able to avoid the use of Reflection which is one condition (along with the "running in the same VM", sorry not to mention that). See the code below:
import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.logging.Logger;
public class Clone
{
public static void main(String args[])
throws Exception
{
// class name
String className = "Dog";
// directory that has the Dog.class file to tell the second Class Loader where to search for the class
String dir = "C:\\temp";
// Logging mechanism
Logger _logger = Logger.getLogger(Clone.class.getName());
// Instance1 get directly from the INSTANCE field variable of the Dog class
Dog dog1 = Dog.INSTANCE;
_logger.info("Loaded " + dog1.getClass().getName() + " [" + dog1.getClass().hashCode()
+ "]");
_logger.info("Instance " + dog1 + " [" + dog1.hashCode()
+ "]");
// Instance 1 misma a la anterior
Dog dog2 = Dog.INSTANCE;
_logger.info("Misma Instance " + dog2 + " [" + dog2.hashCode()
+ "]");
// Creating a second Class loader
ClassLoader classLoader2 = new URLClassLoader(
new URL[] { new File(dir).toURL() });
// we load the class
Class dogClass = classLoader2.loadClass(className);
_logger.info("Loaded " + dogClass.getName() + " [" + dogClass.hashCode()
+ "]");
// Getting the INSTANCE field that has the unique instance of the Dog Class
Field getter = dogClass.getDeclaredField("INSTANCE");
Object obj = new Object[0];
// Getting the value of the INSTANCE field
Dog dog3 = (Dog)getter.get(obj);
// We got a new Dog instance
_logger.info("Instance " + dog3 + " [" + dog3.hashCode()
+ "]");
}
}
However I still have my doubts if this correctly do the trick in showing the Class Loading drawback of a Singleton.
Sure, you can use two classloaders, but (if you want to be picky) the "Dog" classes they load are not the same class, even though they were loaded from the same place. So you only create one instance of each of the two different "Dog" classes.
If you make the class Serializable, the following code does work:
public class Singleton implements Serializable {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static final Singleton getInstance() {
return INSTANCE;
}
static final public void main(final String[] args)
throws Exception {
Singleton first = Singleton.getInstance();
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream objectOut = new ObjectOutputStream(byteOut);
objectOut.writeObject(first);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream objectIn = new ObjectInputStream(byteIn);
Singleton second = (Singleton) objectIn.readObject();
System.out.println(first == second);
}
}
Though if you cannot make the class Serializable and you cannot use reflection, I'm not sure what else you could do.
- Saish
Saisha at 2007-7-15 23:17:40 >

緿oes it make any difference in all the possible solutions you all have suggested if the Singleton class is declared as a subclass of Exception?
public class Dog extends Exception{
public static final Dog INSTANCE = new Dog();
private Dog() {}
@Override
public String toString() {
return "Gua Gua!";
}
}
That was the last update to the trivia I proposed (AN ERRATA).
Thanks in advance for any suggestion.
> 緿oes it make any difference in all the possible> solutions you all have suggested if the Singleton> class is declared as a subclass of Exception?> Yes it does, because Exception implements Serializable, so Dog is all of a sudden Serializable.
I would like to thank you. Your answer was the correct one. There was an omission (not of my own) on the original specification of the trivia. My last post states the Errata made, which implies that the singleton class extends from the Exception class, and as Exception implements the serializable interface, this solution is completely possible to demonstrate that there exist two instances.
So, es5f2000's very first reply was the correct one. :^)- Saish
Saisha at 2007-7-15 23:17:40 >

> I would like to thank you. Your answer was the
> correct one.
Except that one of course must add....
However anyone that actually writes code like this should be fired or treated as a junior programmer because writing code like this totally disregards the nature of software engineering versus that of just understanding what is possible in a language.
And of course no serious engineer need know this except to be able to recognize when another 'developer' is writing code that is not maintainable.