What are the different ways we can break a singleton pattern in Java

java, singleton

Solution

Starting with your given code, "Double-Checked Locking" can be broken at some environment, When run on a system using the Symantec JIT, it doesn't work. In particular, the Symantec JIT compiles

singletons[i].reference = new Singleton();

to the following (note that the Symantec JIT using a handle-based object allocation system).

0206106A   mov         eax,0F97E78h
0206106F   call        01F6B210                  ; allocate space for
                                                 ; Singleton, return result in eax
02061074   mov         dword ptr [ebp],eax       ; EBP is &singletons[i].reference 
                                                ; store the unconstructed object here.
02061077   mov         ecx,dword ptr [eax]       ; dereference the handle to
                                                 ; get the raw pointer
02061079   mov         dword ptr [ecx],100h      ; Next 4 lines are
0206107F   mov         dword ptr [ecx+4],200h    ; Singleton's inlined constructor
02061086   mov         dword ptr [ecx+8],400h
0206108D   mov         dword ptr [ecx+0Ch],0F84030h

As you can see, the assignment to singletons[i].reference is performed before the constructor for Singleton is called. This is completely legal under the existing Java memory model, and also legal in C and C++ (since neither of them have a memory model).

http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

Apart from that

- It can break if the class is `Serializable`

- It can break if its 'Clonable`

- You can break by `Reflection` (I believe)

- it can break ff multiple classloaders are loaded the class

*How do you solve rule breakers?

- It is much safer to do eager initialization

- To prevent deserializing to create new object you may override `readResolve()` method in your class and throw exception

- To prevent cloning, you may overrride `clone()` and throw `CloneNotSupported` exception

- To escape for reflective instantion, we can add check in the constructor and throw exception.

Example

public class Singleton {
 
    private static final Singleton INSTANCE = new Singleton();
 
    private Singleton() {
        // Check if we already have an instance
        if (INSTANCE != null) {
           throw new IllegalStateException("Singleton" +
             " instance already created.");
        }
    }
    public static final Singleton getInstance() {
        return INSTANCE;
    }
    private Object readResolve() throws ObjectStreamException         {
            return INSTANCE;
    }
    private Object writeReplace() throws ObjectStreamException {
            return INSTANCE;
    }
    public Object clone() throws CloneNotSupportedException {
        // return INSTANCE
        throw new CloneNotSupportedException();
    }
}

After all I would suggest to use Enum as the safest way for Singleton (Since java5 the best way to do it is to use an enum)

public static enum SingletonFactory {
    INSTANCE;
    public static SingletonFactory getInstance() {
        return INSTANCE;
    }
}

Problem

What are the different ways we can break a singleton pattern in Java. I know one way i.e. if we do not synchronize the method in singleton , then we can create more than an instance of the class. So synchronization is applied. Is there a way to break singleton java class. ``` public class Singleton { private static Singleton singleInstance; private Singleton() { } public static Singleton getSingleInstance() { if (singleInstance == null) { synchronized (Singleton.class) { if (singleInstance == null) { singleInstance = new Singleton(); } } } return singleInstance; } } ```

Original source