Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save codinko/3ec83734642a88450db75a51ff24e175 to your computer and use it in GitHub Desktop.
Save codinko/3ec83734642a88450db75a51ff24e175 to your computer and use it in GitHub Desktop.
//This is the class that creates the two “Singleton” instances on the same JVM:
import java.lang.reflect.Method;
public class ClassLoaderSingletonBreakingTest {
public static void main(String[] args) {
MyClassLoader cl1 = new MyClassLoader();
Object o1;
try {
Class c = Class.forName("Singleton", true, cl1);
Method m = c.getMethod("getInstance");
o1 = m.invoke(null, new Object[] {});
System.out.println(o1);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Something is wrong here: ", e);
}
Singleton s2 = Singleton.getInstance();
System.out.println(s2);
Singleton s3 = Singleton.getInstance();
System.out.println(s3);
}
}
/////
Result:
Created an instance of Singleton.
Singleton@21g5dg30
Created an instance of Singleton.
Singleton@89g6620
Singleton@89g6620
//---------------------------------
public final class Singleton {
private static Singleton _instance;
private Singleton() {
System.out.println("Created an instance of Singleton.");
}
public static synchronized Singleton getInstance() {
if (_instance == null) {
_instance = new Singleton();
}
return _instance;
}
}
public class MyClassLoader extends ClassLoader {
private static final int BUFFER_SIZE = 8192;
protected synchronized Class loadClass(String className, boolean resolve) throws ClassNotFoundException {
// IS THIS CLASS ALREADY LOADED?
Class cls = findLoadedClass(className);
if (cls != null) {
return cls;
}
// GET CLASS FILE NAME FROM CLASS NAME
String clsFile = className.replace('.', '/') + ".class";
// GETS BYTES FOR CLASS
byte[] classBytes = null;
try {
InputStream in = getResourceAsStream(clsFile);
byte[] buffer = new byte[BUFFER_SIZE];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int n = -1;
while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
out.write(buffer, 0, n);
}
classBytes = out.toByteArray();
} catch (IOException e) {
System.out.println("ERROR loading class file: " + e);
}
if (classBytes == null) {
throw new ClassNotFoundException("Cannot load class: " + className);
}
// TURNS THE BYTE ARRAY INTO A CLASS
try {
cls = defineClass(className, classBytes, 0, classBytes.length);
if (resolve) {
resolveClass(cls);
}
} catch (SecurityException e) {
// LOADING CORE JAVA CLASSES SUCH AS JAVA.LANG.STRING
// IS PROHIBITED, THROWS JAVA.LANG.SECURITYEXCEPTION.
// DELEGATE TO PARENT IF NOT ALLOWED TO LOAD CLASS
cls = super.loadClass(className, resolve);
}
return cls;
}
}
//Reference - https://iolaru.wordpress.com/2011/11/26/two-singleton-instances-inside-the-same-jvm-example/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment