Created
October 4, 2020 07:52
-
-
Save codinko/3ec83734642a88450db75a51ff24e175 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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