Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Tuesday, January 12, 2016

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

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


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;      }  }  

Answer by Dylan Meeus for What are the different ways we can break a singleton pattern in Java


Multithreading is the biggest issue with singletons. You can avoid that by synchronizing or using eager initialisation.

Another way would be to use singleton where you're not supposed to. By using the singleton pattern you might apply it in a way that obstructs your program in later development. (E.G, creating a singleton "player" in a game, because you assume it's a singleplayer game. Next step in development "add co-op functionality").

The singleton pattern has it's advantages, but don't use it without carefull consideration.

Answer by Keerthivasan for What are the different ways we can break a singleton pattern in Java


AFAIK, there are two ways it could be broken

  • Using Reflection

  • When there are custom classloaders, more than one (i.e. parent class loader).all singletons should be loaded by common parent classloader.

Answer by skiwi for What are the different ways we can break a singleton pattern in Java


A note first: It would be better in this case, mainly for readability, to make the whole getSingleInstance() { } synchronized:

public synchronized static Singleton getSingleInstance() {      if (singleInstance == null) {          singleInstance = new Singleton();      }      return singleInstance;  }  

Other than that, I don't think it is easy to break the code. Of course if you add recursive calls then it is possible to break it, like this:

  • Call the constructor of some other class inside this Singleton's constructor.
  • In the constructor of that class, try to obtain this Singleton instance.

But that's the only thing I can think about, and you cannot protect yourself from that in the Singleton class.

Answer by Satheesh Cheveri for What are the different ways we can break a singleton pattern in Java


Starting with your given code, "Double-Checked Locking" can be brocken at some enviroment, 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

  1. It can break if the class is Serializable
  2. It can break if its 'Clonable`
  3. You can break by Reflection (I believe)
  4. it can break ff multiple classloaders are loaded the class

*How do you solve rule breakers?

  1. It is much safer to do eager initialization
  2. To prevent deserializing to create new object you may override readResolve() method in your class and throw exception
  3. To prevent cloning, you may overrride clone() and throw CloneNotSupported exception
  4. 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;      }  }  

Answer by Evgeniy Dorofeev for What are the different ways we can break a singleton pattern in Java


One way is Serialization. If you do not implement readResolve then reading a singleton with ObjectInputStream.readObject() will return a new instance of this singleton.

Answer by Sean Patrick Floyd for What are the different ways we can break a singleton pattern in Java


Actually a safe version without the need for synchronization is the version with a nested holder class:

public final class Singleton{      public static final Singleton getInstance(){      // no need for synchronization since the classloader guarantees to initialize      // Holder.INSTANCE exactly once before handing out a reference to it      return Holder.INSTANCE;    }    private Singleton();    private static class Holder{      private static final Singleton INSTANCE = new Singleton();    }  }  

Other safe versions are:

  • Eager initialization

    public final class Singleton{      public static final Singleton getInstance(){          return INSTANCE;      }      private Singleton();      private static final Singleton INSTANCE = new Singleton();  }  
  • Enum Singleton

    public enum Singleton{      INSTANCE;  }  

All of these versions have pros and cons, but none of them needs explicit synchronization since they all rely on the ClassLoader and its built-in Thread safety.

As the others have written, you can break some of these patterns through Deserialization. Read Effective Java by Joshua Bloch (Items 74 to 78) about preventing such attacks (the enum singleton pattern is safe against such attacks out of the box).

Answer by Tim B for What are the different ways we can break a singleton pattern in Java


The synchronized approach will work, but will also slow down every access to the singleton to protect something that only ever happens in the first access.

The simplest and safest way is just to do eager initialization, that is always safe as Java guarantees all member variables are set before it lets anyone access them.

public class Singleton {      private static Singleton singleInstance = new Singleton();        private Singleton() {      }        public static Singleton getSingleInstance() {          return singleInstance;      }  }  

Your current approach is actually broken even with your synchronized loop - because double-check locking is broken. You need to mark the singleton variable as volatile if you are going to use it for double-check locking since otherwise there are still ways for threads to access an incompletely-initialized object. See http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java for more details.

Answer by Kuldeep Singh for What are the different ways we can break a singleton pattern in Java


Suppose you have implemented Singleton class as "SingletonPattern" as below. package com.example.pattern;

public class SingletonPattern  {    private static SingletonPattern pattern;      public static SingletonPattern getInstance()    {      if (pattern == null)      {        synchronized (SingletonPattern.class)        {          if (pattern == null)          {            pattern = new SingletonPattern();          }        }      }      return pattern;    }  }  

Now you can break you the Singleton behavior of this class by using following approach.

Class c = Class.forName("com.example.pattern.SingletonPattern");  System.out.println((SingltonPattern) c.newInstance());  


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.