From b2a0fcd76bcf6eaa70c99d530b383c6711239ec6 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 6 Jul 2020 16:10:46 +0000 Subject: [PATCH] BAEL-4302 : How can I list all classes loaded in a specific class loader --- .../loadedclasslisting/ClassLoaderType.java | 6 +++ .../baeldung/loadedclasslisting/Launcher.java | 51 +++++++++++++++++++ .../ListLoadedClassesAgent.java | 46 +++++++++++++++++ .../baeldung/loadedclasslisting/MANIFEST.MF | 1 + .../customLoader/ClassLoaderInfo.java | 12 +++++ .../customLoader/CustomClassLoader.java | 32 ++++++++++++ 6 files changed, 148 insertions(+) create mode 100644 core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ClassLoaderType.java create mode 100644 core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/Launcher.java create mode 100644 core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ListLoadedClassesAgent.java create mode 100644 core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/MANIFEST.MF create mode 100644 core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/customLoader/ClassLoaderInfo.java create mode 100644 core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/customLoader/CustomClassLoader.java diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ClassLoaderType.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ClassLoaderType.java new file mode 100644 index 0000000000..1111fc21fe --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ClassLoaderType.java @@ -0,0 +1,6 @@ +package com.baeldung.loadedclasslisting; + +public enum ClassLoaderType { + + SYSTEM, EXTENSION, BOOTSTRAP, CUSTOM +} diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/Launcher.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/Launcher.java new file mode 100644 index 0000000000..19c42dfd8d --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/Launcher.java @@ -0,0 +1,51 @@ +package com.baeldung.loadedclasslisting; + +import java.lang.reflect.Method; +import java.util.Arrays; + +import com.baeldung.loadedclasslisting.customLoader.ClassLoaderInfo; +import com.baeldung.loadedclasslisting.customLoader.CustomClassLoader; + +public class Launcher { + + private static ClassLoader customClassLoader; + + public static void main(String[] args) { + + printClassesLoadedBy(ClassLoaderType.BOOTSTRAP); + + printClassesLoadedBy(ClassLoaderType.SYSTEM); + + printClassesLoadedBy(ClassLoaderType.EXTENSION); + + printClassesLoadedBy(ClassLoaderType.CUSTOM); + } + + private static void printClassesLoadedBy(ClassLoaderType classLoaderType) { + Class[] classes; + if (classLoaderType.equals(ClassLoaderType.CUSTOM)) { + customClassLoader = customClassLoading(); + classes = ListLoadedClassesAgent.listLoadedClasses(customClassLoader); + } else { + classes = ListLoadedClassesAgent.listLoadedClasses(classLoaderType); + } + Arrays.asList(classes) + .forEach(clazz -> System.out.println( + classLoaderType + " ClassLoader : " + clazz.getCanonicalName())); + } + + private static CustomClassLoader customClassLoading() { + CustomClassLoader customClassLoader = new CustomClassLoader(); + Class c; + try { + c = customClassLoader.findClass(ClassLoaderInfo.class.getName()); + Object ob = c.getDeclaredConstructor() + .newInstance(); + Method md = c.getMethod("printClassLoaders"); + md.invoke(ob); + } catch (Exception e) { + e.printStackTrace(); + } + return customClassLoader; + } +} diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ListLoadedClassesAgent.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ListLoadedClassesAgent.java new file mode 100644 index 0000000000..03907f8b04 --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/ListLoadedClassesAgent.java @@ -0,0 +1,46 @@ +package com.baeldung.loadedclasslisting; + +import java.lang.instrument.Instrumentation; + +public class ListLoadedClassesAgent { + + private static Instrumentation instrumentation; + + public static void premain(String agentArgs, Instrumentation instrumentation) { + ListLoadedClassesAgent.instrumentation = instrumentation; + } + + public static Class[] listLoadedClasses(ClassLoaderType classLoaderType) { + if (instrumentation == null) { + throw new IllegalStateException( + "ListLoadedClassesAgent is not initialized."); + } + return instrumentation.getInitiatedClasses( + getClassLoader(classLoaderType)); + } + + public static Class[] listLoadedClasses(ClassLoader classLoader) { + if (instrumentation == null) { + throw new IllegalStateException( + "ListLoadedClassesAgent is not initialized."); + } + return instrumentation.getInitiatedClasses(classLoader); + } + + private static ClassLoader getClassLoader(ClassLoaderType classLoaderType) { + ClassLoader classLoader = null; + switch (classLoaderType) { + case SYSTEM: + classLoader = ClassLoader.getSystemClassLoader(); + break; + case EXTENSION: + classLoader = ClassLoader.getSystemClassLoader().getParent(); + break; + case BOOTSTRAP: + break; + default: + break; + } + return classLoader; + } +} diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/MANIFEST.MF b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/MANIFEST.MF new file mode 100644 index 0000000000..4a60bda0b7 --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/MANIFEST.MF @@ -0,0 +1 @@ +Premain-Class: com.baeldung.loadedclasslisting.ListLoadedClassesAgent \ No newline at end of file diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/customLoader/ClassLoaderInfo.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/customLoader/ClassLoaderInfo.java new file mode 100644 index 0000000000..a787b062d5 --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/customLoader/ClassLoaderInfo.java @@ -0,0 +1,12 @@ +package com.baeldung.loadedclasslisting.customLoader; + +import java.util.ArrayList; + +public class ClassLoaderInfo { + + public void printClassLoaders() throws ClassNotFoundException { + + System.out.println("Classloader of this class:" + ClassLoaderInfo.class.getClassLoader()); + System.out.println("Classloader of ArrayList:" + ArrayList.class.getClassLoader()); + } +} diff --git a/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/customLoader/CustomClassLoader.java b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/customLoader/CustomClassLoader.java new file mode 100644 index 0000000000..a5f293f605 --- /dev/null +++ b/core-java-modules/core-java-jvm-2/src/main/java/com/baeldung/loadedclasslisting/customLoader/CustomClassLoader.java @@ -0,0 +1,32 @@ +package com.baeldung.loadedclasslisting.customLoader; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +public class CustomClassLoader extends ClassLoader { + + @Override + public Class findClass(String name) throws ClassNotFoundException { + byte[] b = loadClassFromFile(name); + return defineClass(name, b, 0, b.length); + } + + private byte[] loadClassFromFile(String fileName) { + InputStream inputStream = getClass().getClassLoader() + .getResourceAsStream(fileName.replace('.', File.separatorChar) + ".class"); + byte[] buffer; + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + int nextValue = 0; + try { + while ((nextValue = inputStream.read()) != -1) { + byteStream.write(nextValue); + } + } catch (IOException e) { + e.printStackTrace(); + } + buffer = byteStream.toByteArray(); + return buffer; + } +}