DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Cutting-Edge Object Detection for Autonomous Vehicles: Advanced Transformers and Multi-Sensor Fusion
  • Writing DTOs With Java8, Lombok, and Java14+
  • Graph API for Entra ID (Azure AD) Object Management
  • A Comprehensive Guide to IAM in Object Storage

Trending

  • Scaling Mobile App Performance: How We Cut Screen Load Time From 8s to 2s
  • Analyzing “java.lang.OutOfMemoryError: Failed to create a thread” Error
  • Enhancing Security With ZTNA in Hybrid and Multi-Cloud Deployments
  • Understanding and Mitigating IP Spoofing Attacks
  1. DZone
  2. Coding
  3. Languages
  4. Prevent Breaking a Singleton Class Pattern

Prevent Breaking a Singleton Class Pattern

Let's explore the three major ways in which you can break a singleton property — and how to prevent it.

By 
Madhuka  Udantha user avatar
Madhuka Udantha
·
Updated Sep. 05, 19 · Tutorial
Likes (9)
Comment
Save
Tweet
Share
88.5K Views

Join the DZone community and get the full member experience.

Join For Free

Image title

Learn how to avoid breaking a Singleton class pattern

We are used to having a singleton design pattern in our applications whenever it is needed. As we know, in the singleton design pattern, we can only create one instance and access it in the whole application. But in some cases, it will break the singleton behavior.

You may also like: All About the Singleton

There are mainly three concepts in which we can break the singleton property of a Singleton class in Java. In this post, we will discuss how it can break and how to prevent it.

Here is sample Singleton class and SingletonTest class.

Singleton.Java

package demo1;

public final class Singleton {

    private static volatile Singleton instance = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}


SingletonTest.java

  package demo1;

public class SingletonTest {
    public static void main(String[] args) {
        Singleton object1 = Singleton.getInstance();
        Singleton object2 = Singleton.getInstance();
        System.out.println("Hashcode of Object 1 - " + object1.hashCode());
        System.out.println("Hashcode of Object 2 - " + object2.hashCode());
    }
} 


Here is output; you can see it has the same hashcode for objectOne and objectTwo:

Hashcode of Object 1 - 1836019240
Hashcode of Object 2 - 1836019240


Now, we will break this pattern. First, we will use Java reflection.

Reflection

Java Reflection is an API used to examine or modify the behavior of methods, classes, and interfaces at runtime. Using the Reflection API, we can create multiple objects in the Singleton class. Consider the following example:

ReflectionSingleton.java

  package demo1;

import java.lang.reflect.Constructor;

public class ReflectionSingleton {
    public static void main(String[] args)  {

        Singleton objOne = Singleton.getInstance();
        Singleton objTwo = null;
        try {
            Constructor constructor = Singleton.class.getDeclaredConstructor();
            constructor.setAccessible(true);
            objTwo = (Singleton) constructor.newInstance();
        } catch (Exception ex) {
            System.out.println(ex);
        }

        System.out.println("Hashcode of Object 1 - "+objOne.hashCode());
        System.out.println("Hashcode of Object 2 - "+objTwo.hashCode());

    }
}   


This example shows how reflection can break the singleton pattern with Java reflect. You will get two hash codes, as shown below. It has a break on the singleton pattern.

Prevent Singleton Pattern From Reflection

There are many ways to prevent Singleton pattern from Reflection API, but one of the best solutions is to throw a run-time exception in the constructor if the instance already exists. In this, we can not able to create a second instance.

Deserialization

In serialization, we can save the object of a byte stream into a file or send over a network. Suppose if you serialize the Singleton class, and then again de-serialize that object, it will create a new instance, hence deserialization will break the Singleton pattern.

The below code is used to illustrate how the Singleton pattern breaks with deserialization.

Implements Serializable interface for Singleton Class.

DeserializationSingleton.Java

package demo1;

import java.io.*;

public class DeserializationSingleton {

    public static void main(String[] args) throws Exception {

        Singleton instanceOne = Singleton.getInstance();
        ObjectOutput out = new ObjectOutputStream(new FileOutputStream("file.text"));
        out.writeObject(instanceOne);
        out.close();

        ObjectInput in = new ObjectInputStream(new FileInputStream("file.text"));
        Singleton instanceTwo = (Singleton) in.readObject();
        in.close();

        System.out.println("hashCode of instance 1 is - " + instanceOne.hashCode());
        System.out.println("hashCode of instance 2 is - " + instanceTwo.hashCode());
    }

}


The output is below, and you can see two hashcodes.

hashCode of instance 1 is - 2125039532
hashCode of instance 2 is - 381259350


Prevent Singleton Pattern From Deserialization

To overcome this issue, we need to override readResolve() method in the Singleton class and return the same Singleton instance. Update Singleton.java, with below method.

   protected Object readResolve() { 
           return instance; 
     }  


Now, run the above DeserializationDemo class and see the output.

hashCode of instance 1 is - 2125039532
hashCode of instance 2 is - 2125039532


Cloning

Using the "clone" method, we can create a copy of the original object; it's the same thing if we applied clone in the singleton pattern. It will create two instances: one original and another one cloned object. In this case, we will break the Singleton principle, as shown in the below code.

Implement the " Cloneable" interface and override the clone method in the above Singleton class.

Singleton.java

    @Override
    protected Object clone() throws CloneNotSupportedException  {
        return super.clone();
    }


Then, test with cloning for breaking the singleton.

CloningSingleton.java

public class CloningSingleton {
    public static void main(String[] args) throws CloneNotSupportedException, Exception {
        Singleton instanceOne = Singleton.getInstance();
        Singleton instanceTwo = (Singleton) instanceOne.clone();
        System.out.println("hashCode of instance 1 - " + instanceOne.hashCode());
        System.out.println("hashCode of instance 2 - " + instanceTwo.hashCode());
    }

}


Here is the output:

hashCode of instance 1 - 1836019240
hashCode of instance 2 - 325040804


If we see the above output, two instances have different hashcodes. This means these instances are not the same.

Prevent Singleton Pattern From Cloning

In the above code, it breaks the Singleton principle, i. e created two instances. To overcome the above issue, we need to implement/override the clone() method and throw an exception CloneNotSupportedException from the clone method. If anyone tries to create a clone object of Singleton, it will throw an exception, as shown in the below code.

    @Override
    protected Object clone() throws CloneNotSupportedException  {
        throw new CloneNotSupportedException();
    }


Now, we can run the CloningSingleton class; it will throw CloneNotSupportedException while creating a clone object of the Singleton object.

Hope you found this post useful!

Further Reading

All About the Singleton

Singleton Pattern: A Deep Dive

Singleton pattern Object (computer science)

Published at DZone with permission of Madhuka Udantha, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Cutting-Edge Object Detection for Autonomous Vehicles: Advanced Transformers and Multi-Sensor Fusion
  • Writing DTOs With Java8, Lombok, and Java14+
  • Graph API for Entra ID (Azure AD) Object Management
  • A Comprehensive Guide to IAM in Object Storage

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!