In this blog I want to show implementation pitfalls of the singleton pattern and show you why enums are the better singletons.

The singleton pattern is widely known and discussed a lot of times. Developers often prefer to implement a singleton using a final static field. But this approach has some pitfalls or rather malicious code can compromise the singleton pattern. In the next sections I will show you the possible attacks on singleton implementations that compromise the pattern. Maybe you will use this techniques to implement a kind of workaround some day, but I hope you will not.

Static Final Field Singleton

The purpose of a singleton is that only 1 instance of a class will ever exist. To ensure this the first thought that will come in your mind is to use a constant (static final field) and a private constructor. Thus the widely-used singleton implementation is

Reflection bypass

Don’t think that a declaring a constant and making a constructor privat is enough to ensure that only one instance will ever exist. If malicious code uses reflection it can create another instance of the class.

The output will be something like this:

Reflection bypass prevention by caller check

We can prevent this if we implement a caller check in the constructor so that only the class initializer of ConstantSingleton1 can instantiate it.

This will make the ConstantSingleton2 really a singleton. But maybe your singleton also implements Serializable. Then malicious code has another option to compromise the singleton pattern.

Serialization bypass

Even we implemented a reflection prevention there are still options for malicious code to create a new instance if the singleton is also Serializable.

Malicious code can serialize/deserialize the singleton. Since the deserialization mechanism only create a new object but does not execute the constructor (or to be more precise initializer) code the reflection prevention does not work.

The output will be something like this:

Serialization bypass prevention by readResolve

As you can see the malicious code could create a new instance using serialization. But hopefully the java serialization mechanism provides the tools to prevent this.

To prevent the serialization bypass one can implement a private Object readResolve() method that will return the already existent singleton instance on deserialization every time.

Now malicious code has no chance.

The output will be something like this:

Static Final Field Conclusion

As you could see you have to do a lot to keep your singletons really singletons and you have even more to do if they are Serializable. So you might ask yourself if there is a better and safer way to implement a real singleton that needs less code.

Fortunately there is a better way since Java 1.5 – use enums.

Enum Singleton

Java 1.5 introduced enums and they are great for implementing real singletons, because the nature of an enum itself makes the singleton a real singleton. By definition there is always only 1 instance of an enum instance and you don’t have any options to bypass this.

So with enums you would implement a singleton like this

That’s all it’s easy isn’t it.

Malicious code can not use reflection nor serialization to create a new instance, because java will prevent it. So if malicious code tries this:

The output will be

Conclusion

If you want to implement a real singleton and you can use Java 1.5 or above you should use enums to do it. They need less code and are safe.

Example source code available at https://github.com/link-intersystems/blog/tree/master/singleton-implementation-pitfalls