/commons/src/main/java/com/navercorp/pinpoint/common/util/ClassLoaderUtils.java

https://github.com/naver/pinpoint · Java · 118 lines · 70 code · 17 blank · 31 comment · 15 complexity · ef1e1fe78426f7c25b5686965e2d446d MD5 · raw file

  1. /*
  2. * Copyright 2014 NAVER Corp.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.navercorp.pinpoint.common.util;
  17. /**
  18. * @author emeroad
  19. */
  20. public final class ClassLoaderUtils {
  21. public static final ClassLoaderCallable DEFAULT_CLASS_LOADER_CALLABLE = new ClassLoaderCallable() {
  22. @Override
  23. public ClassLoader getClassLoader() {
  24. return ClassLoaderUtils.class.getClassLoader();
  25. }
  26. };
  27. private static final ClassLoader SYSTEM_CLASS_LOADER;
  28. private static final ClassLoader EXT_CLASS_LOADER;
  29. private static final ClassLoader BOOT_CLASS_LOADER;
  30. static {
  31. BOOT_CLASS_LOADER = Object.class.getClassLoader();
  32. // SystemClassLoader can be changed by "java.system.class.loader"
  33. // https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html
  34. // If the system property "java.system.class.loader" is defined when this method is first invoked
  35. // then the value of that property is taken to be the name of a class that will be returned as the system class loader.
  36. final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
  37. EXT_CLASS_LOADER = findChildClassLoader(BOOT_CLASS_LOADER, systemClassLoader);
  38. SYSTEM_CLASS_LOADER = findChildClassLoader(EXT_CLASS_LOADER, systemClassLoader);
  39. }
  40. private static ClassLoader findChildClassLoader(ClassLoader parent, ClassLoader searchTarget) {
  41. ClassLoader prev = searchTarget;
  42. while (parent != prev.getParent()) {
  43. prev = prev.getParent();
  44. }
  45. return prev;
  46. }
  47. private ClassLoaderUtils() {
  48. }
  49. // TODO check @CallerSensitive, Reflection.getCallerClass()
  50. // private static ClassLoader getClassLoader(ClassLoader classLoader) {
  51. // if (classLoader == null) {
  52. // return ClassLoader.getSystemClassLoader();
  53. // }
  54. // return classLoader;
  55. // }
  56. public static ClassLoader getDefaultClassLoader() {
  57. return getDefaultClassLoader(DEFAULT_CLASS_LOADER_CALLABLE);
  58. }
  59. public static ClassLoader getDefaultClassLoader(ClassLoaderCallable defaultClassLoaderCallable) {
  60. if (defaultClassLoaderCallable == null) {
  61. throw new NullPointerException("defaultClassLoaderCallable");
  62. }
  63. try {
  64. final Thread th = Thread.currentThread();
  65. final ClassLoader contextClassLoader = th.getContextClassLoader();
  66. if (contextClassLoader != null) {
  67. return contextClassLoader;
  68. }
  69. } catch (Throwable ignore) {
  70. // skip
  71. }
  72. // Timing for security exceptions is different when the ClassLoader is received as an argument
  73. return defaultClassLoaderCallable.getClassLoader();
  74. }
  75. public interface ClassLoaderCallable {
  76. ClassLoader getClassLoader();
  77. }
  78. public static boolean isJvmClassLoader(ClassLoader classLoader) {
  79. if (BOOT_CLASS_LOADER == classLoader || SYSTEM_CLASS_LOADER == classLoader || EXT_CLASS_LOADER == classLoader) {
  80. return true;
  81. }
  82. return false;
  83. }
  84. public static String dumpStandardClassLoader() {
  85. final StringBuilder buffer = new StringBuilder();
  86. appendClassLoaderLog(buffer, "SYSTEM_CLASS_LOADER", SYSTEM_CLASS_LOADER);
  87. appendClassLoaderLog(buffer, "EXT_CLASS_LOADER", EXT_CLASS_LOADER);
  88. appendClassLoaderLog(buffer, "BOOT_CLASS_LOADER", BOOT_CLASS_LOADER);
  89. return buffer.toString();
  90. }
  91. private static void appendClassLoaderLog(StringBuilder buffer, String classLoaderName, ClassLoader classLoader) {
  92. buffer.append(classLoaderName);
  93. buffer.append(':');
  94. if (classLoader == null) {
  95. buffer.append("null");
  96. } else {
  97. buffer.append(classLoader.toString());
  98. }
  99. buffer.append(", ");
  100. }
  101. }