sun.misc.URLClassPath 解析

阅读: 评论:0

sun.misc.URLClassPath 解析

sun.misc.URLClassPath 解析

作用:Java 中加载类和查找资源的路径
jdk8
.java
jdk9
.base/share/classes/jdk/internal/loader/URLClassPath.java
jdk10
.base/share/classes/jdk/internal/loader/URLClassPath.java
jdk11
.base/share/classes/jdk/internal/loader/URLClassPath.java
jdk12
.base/share/classes/jdk/internal/loader/URLClassPath.java
jdk13
.base/share/classes/jdk/internal/loader/URLClassPath.java

本文针对 jdk8

属性

// 保存所有的查找路径  private ArrayList<URL> path = new ArrayList<>();Stack<URL> urls = new Stack<>();// 初始为空,根据 urls 生成 loadersArrayList<Loader> loaders = new ArrayList<>();// 判断路径和 jar 包是否有相应的 Loader,没有才会放入 loaders 和 lmapHashMap<String, Loader> lmap = new HashMap<>();

构造方法

/**                                                                                         * 根据给定的 URL 创建 URLClassPath                                                                * 使用给定的 URL 顺序查找 Resource 和 jar                                                            * 如果 URL 以 '/' 结尾则被认定为路径,否则被认定为 jar 文件                                                     */                                                                                         
public URLClassPath(URL[] urls, URLStreamHandlerFactory factory, AccessControlContext acc) {for (int i = 0; i < urls.length; i++) {                                                 path.add(urls[i]);                                                                  }                                                                                       push(urls);                                                                             if (factory != null) {                                                                  jarHandler = ateURLStreamHandler("jar");                                 }                                                                                       if (DISABLE_ACC_CHECKING) {                                                             this.acc = null;                                                                    } else {                                                                                this.acc = acc;                                                                     }                                                                                       
}                                                                                                                                                                                      
public URLClassPath(URL[] urls) { this(urls, null, null); }                                                                                                                                                                                       
public URLClassPath(URL[] urls, AccessControlContext acc) { this(urls, null, acc); }                                                                                       

URLClassPath 在哪里被使用到

public URLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) {   super(parent);                                         // this is to make the stack depth consistent with 1.1 SecurityManager security = SecurityManager();if (security != null) {                                security.checkCreateClassLoader();                 }                                                      acc = Context();                   ucp = new URLClassPath(urls, factory, acc);            
}public URLClassLoader(URL[] urls, ClassLoader parent) {    super(parent);                                         // this is to make the stack depth consistent with 1.1 SecurityManager security = SecurityManager();if (security != null) {                                security.checkCreateClassLoader();                 }                                                      this.acc = Context();              ucp = new URLClassPath(urls, acc);                     
}URLClassLoader(URL[] urls, ClassLoader parent, AccessControlContext acc) {                 super(parent);                                         // this is to make the stack depth consistent with 1.1 SecurityManager security = SecurityManager();if (security != null) {                                security.checkCreateClassLoader();                 }                                                      this.acc = acc;                                        ucp = new URLClassPath(urls, acc);                     
}public URLClassLoader(URL[] urls) {                        super();                                               // this is to make the stack depth consistent with 1.1 SecurityManager security = SecurityManager();if (security != null) {                                security.checkCreateClassLoader();                 }                                                      this.acc = Context();              ucp = new URLClassPath(urls, acc);                     
} URLClassLoader(URL[] urls, AccessControlContext acc) {      super();                                                // this is to make the stack depth consistent with 1.1  SecurityManager security = SecurityManager(); if (security != null) {                                 security.checkCreateClassLoader();                  }                                                       this.acc = acc;                                         ucp = new URLClassPath(urls, acc);                      
}                                                           

jdk1.8中 AppClassLoader 和 ExtClassLoader 都继承于 URLClassLoader,生成 UrlClassPath 的时候:
AppClassLoader 传入"java.class.path"对应的路径
ExtClassLoader 传入"" 对应的路径

// 儿子找爹可以通过 *.ClassLoader()实现,爹找儿子属于 JVM 实现层级上的东西,随时可能在版本迭代中被删除。
private static native int[] getLookupCacheForClassLoader(ClassLoader loader, String name); private synchronized int[] getLookupCache(String name) {                                                      if (lookupCacheURLs == null || !lookupCacheEnabled) {                                                     return null;                                                                                          }                                                                                                         int[] cache = getLookupCacheForClassLoader(lookupCacheLoader, name);                                      if (cache != null && cache.length > 0) {                                                                  int maxindex = cache[cache.length - 1]; // cache[] is strictly ascending.                             if (!ensureLoaderOpened(maxindex)) {                                                                  if (DEBUG_LOOKUP_CACHE) {                                                                         System.out.println("Expanded loaders FAILED " + loaders.size() + " for maxindex=" + maxindex);}                                                                                                 return null;                                                                                      }                                                                                                     }                                                                                                         return cache;                                                                                             
}                                                                                                             public Resource getResource(String name, boolean check) {                if (DEBUG) {                                                         println(&#Resource("" + name + "")");}                                                                    Loader loader;                                                       int[] cache = getLookupCache(name);                                  for (int i = 0; (loader = getNextLoader(cache, i)) != null; i++) {   Resource res = Resource(name, check);                  if (res != null) {                                               return res;                                                  }                                                                }                                                                    return null;                                                         
}                                                                        private synchronized Loader getNextLoader(int[] cache, int index) {                                           if (closed) {                                                                                             return null;                                                                                          }                                                                                                         if (cache != null) {                                                                                      if (index < cache.length) {                                                                           Loader loader = (cache[index]);                                                        if (DEBUG_LOOKUP_CACHE) {                                                                         System.out.println("HASCACHE: Loading from : " + cache[index] + " = " + BaseURL()); }                                                                                                 return loader;                                                                                    } else {                                                                                              return null; // finished iterating over cache[]                                                   }                                                                                                     } else {                                                                                                  return getLoader(index);                                                                              }                                                                                                         
} private synchronized Loader getLoader(int index) {                                         if (closed) {                                                                          return null;                                                                       }                                                                                      // Expand URL search path until the request can be satisfied or the URL stack is empty.                                                          while (loaders.size() < index + 1) {                                                   // Pop the next URL from the URL stack                                             URL url;                                                                           synchronized (urls) {                                                              if (pty()) {                                                            return null;                                                               } else {                                                                       url = urls.pop();                                                          }                                                                              }                                                                                  // Skip this URL if it already has a Loader. (Loader may be null in the case where URL has not been opened but is referenced by a JAR index.)                                              String urlNoFragString = URLUtil.urlNoFragString(url);                             if (ainsKey(urlNoFragString)) {                                           continue;                                                                      }                                                                                  // Otherwise, create a new Loader for the URL.                                     Loader loader;                                                                     try {                                                                              loader = getLoader(url);                                                       // If the loader defines a local class path then add the URLs to the list of URLs to be opened.                                      URL[] urls = ClassPath();                                            if (urls != null) {                                                            push(urls);                                                                }                                                                              } catch (IOException e) {                                                          // Silently ignore                                                   continue;                                                                      } catch (SecurityException se) {                                                   // Always silently ignore. The context, if there is one, that this URLClassPath was given during construction will never have permission to access the URL.                                          if (DEBUG) {                                                                   println("Failed to access " + url + ", " + se);                 }                                                                              continue;                                                                      }                                                                                  // Finally, add the Loader to the search path.                                     validateLookupCache(loaders.size(), urlNoFragString);                              loaders.add(loader);                                                               lmap.put(urlNoFragString, loader);                                                 }                                                                                      if (DEBUG_LOOKUP_CACHE) {                                                              System.out.println("NOCACHE: Loading from : " + index);                            }                                                                                      (index);                                                             
}// 根据 url 生成 Loader
private Loader getLoader(final URL url) throws IOException {                  try {                                                                     return java.security.AccessController.doPrivileged(                   new java.security.PrivilegedExceptionAction<Loader>() {       @Override                                                 public Loader run() throws IOException {                  String file = File();                          if (file != null && dsWith("/")) {             if ("file".Protocol())) {           return new FileLoader(url);                   } else {                                          return new Loader(url);                       }                                                 } else {                                              return new JarLoader(url, jarHandler, lmap, acc); }                                                     }                                                         }, acc);                                                      } catch (java.security.PrivilegedActionException pae) {                   throw (IOException) Exception();                               }                                                                         
}
// 新添加进去的导致查找缓存失效
private synchronized void validateLookupCache(int index, String urlNoFragString) {                                      if (lookupCacheURLs != null && lookupCacheEnabled) {                                                                if (index < lookupCacheURLs.length && urlNoFragString.equals(URLUtil.urlNoFragString(lookupCacheURLs[index]))) {return;                                                                                                     }                                                                                                               if (DEBUG || DEBUG_LOOKUP_CACHE) {                                                                              System.out.println("WARNING: resource lookup cache invalidated " + "for lookupCacheLoader at " + index);    }                                                                                                               disableAllLookupCaches(); // lookupCacheEnabled = false;                                                                                       }                                                                                                                   
}// 操作 urls 的几个方法
// getLoader(int index) 中// 增加查找路径                                                   
public synchronized void addURL(URL url) {                  if (closed) {                                           return;                                             }                                                       synchronized (urls) {                                   if (url == null || ains(url)) {            return;                                         }                                                   // 在 Stack 的头部添加元素          urls.add(0, url);                                   path.add(url);                                      if (lookupCacheURLs != null) {                      // 查找缓存是静态的("java.class.path"、&#dirs"),动态添加的查找缓存导致其不可使用                    disableAllLookupCaches();                       }                                                   }                                                       
}// java.URLClassLoader
private final URLClassPath ucp;
// java.URLClassLoader#addURL
protected void addURL(URL url) {  ucp.addURL(url);              
}                                 

getLookupCache 查找缓存是为了提高查找速度,作用如下:
如果 lookupCacheURLs包 含{a.jar,b.jar,c.jar,d.jar},并且包“ foo”仅存在于a.jar和c.jar中,则getLookupCache(“ foo / Bar.class”)将返回 {0,2}。
作用和 sun.misc.MetaIndex 差不多
关于&#SavedProperty(“ableSharedLookupCache”)

ableSharedLookupCache 是 JVM 实现层面的参数。

URLClassPath 查找缓存相关的代码在 jdk9 中已经被删除
.html

参考

本文发布于:2024-02-04 23:29:37,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170718848460744.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:sun   misc   URLClassPath
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23