You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LoaderClassPath.java 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
  4. *
  5. * The contents of this file are subject to the Mozilla Public License Version
  6. * 1.1 (the "License"); you may not use this file except in compliance with
  7. * the License. Alternatively, the contents of this file may be used under
  8. * the terms of the GNU Lesser General Public License Version 2.1 or later,
  9. * or the Apache License Version 2.0.
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. */
  16. package javassist;
  17. import java.io.InputStream;
  18. import java.net.URL;
  19. import java.lang.ref.WeakReference;
  20. /**
  21. * A class search-path representing a class loader.
  22. *
  23. * <p>It is used for obtaining a class file from the given
  24. * class loader by <code>getResourceAsStream()</code>.
  25. * The <code>LoaderClassPath</code> refers to the class loader through
  26. * <code>WeakReference</code>. If the class loader is garbage collected,
  27. * the other search pathes are examined.
  28. *
  29. * <p>The given class loader must have both <code>getResourceAsStream()</code>
  30. * and <code>getResource()</code>.
  31. *
  32. * <p>Class files in a named module are private to that module.
  33. * This method cannot obtain class files in named modules.
  34. * </p>
  35. *
  36. * @author <a href="mailto:bill@jboss.org">Bill Burke</a>
  37. * @author Shigeru Chiba
  38. *
  39. * @see ClassPool#insertClassPath(ClassPath)
  40. * @see ClassPool#appendClassPath(ClassPath)
  41. * @see ClassClassPath
  42. * @see ModuleClassPath
  43. */
  44. public class LoaderClassPath implements ClassPath {
  45. private WeakReference clref;
  46. /**
  47. * If true, this search path implicitly includes
  48. * a {@code ModuleClassPath} as a fallback.
  49. * For backward compatibility, this field is set to true
  50. * if the JVM is Java 9 or later. It can be false in
  51. * Java 9 but the behavior of {@code LoadClassPath} will
  52. * be different from its behavior in Java 8 or older.
  53. *
  54. * <p>This field must be false if the JVM is Java 8 or older.
  55. *
  56. * @since 3.21
  57. */
  58. public static boolean fallbackOnModuleClassPath
  59. = javassist.bytecode.ClassFile.MAJOR_VERSION >= javassist.bytecode.ClassFile.JAVA_9;
  60. private static ModuleClassPath moduleClassPath = null;
  61. private boolean doFallback;
  62. /**
  63. * Creates a search path representing a class loader.
  64. */
  65. public LoaderClassPath(ClassLoader cl) {
  66. this(cl, fallbackOnModuleClassPath);
  67. }
  68. LoaderClassPath(ClassLoader cl, boolean fallback) {
  69. clref = new WeakReference(cl);
  70. doFallback = fallback;
  71. if (fallback)
  72. synchronized (LoaderClassPath.class) {
  73. if (moduleClassPath == null)
  74. moduleClassPath = new ModuleClassPath();
  75. }
  76. }
  77. public String toString() {
  78. Object cl = null;
  79. if (clref != null)
  80. cl = clref.get();
  81. return cl == null ? "<null>" : cl.toString();
  82. }
  83. /**
  84. * Obtains a class file from the class loader.
  85. * This method calls <code>getResourceAsStream(String)</code>
  86. * on the class loader.
  87. */
  88. public InputStream openClassfile(String classname) throws NotFoundException {
  89. String cname = classname.replace('.', '/') + ".class";
  90. ClassLoader cl = (ClassLoader)clref.get();
  91. if (cl == null)
  92. return null; // not found
  93. else {
  94. InputStream is = cl.getResourceAsStream(cname);
  95. if (is == null && doFallback)
  96. return moduleClassPath.openClassfile(classname);
  97. else
  98. return is;
  99. }
  100. }
  101. /**
  102. * Obtains the URL of the specified class file.
  103. * This method calls <code>getResource(String)</code>
  104. * on the class loader.
  105. *
  106. * @return null if the class file could not be found.
  107. */
  108. public URL find(String classname) {
  109. String cname = classname.replace('.', '/') + ".class";
  110. ClassLoader cl = (ClassLoader)clref.get();
  111. if (cl == null)
  112. return null; // not found
  113. else {
  114. URL url = cl.getResource(cname);
  115. if (url == null && doFallback)
  116. return moduleClassPath.find(classname);
  117. else
  118. return url;
  119. }
  120. }
  121. /**
  122. * Closes this class path.
  123. */
  124. public void close() {
  125. clref = null;
  126. }
  127. }