public static CoprocessorClassLoader getClassLoader(final Path path, final ClassLoader parent,
    final String pathPrefix, final Configuration conf) throws IOException {
    CoprocessorClassLoader cl = getIfCached(path);
    String pathStr = path.toString();
    if (cl != null) {
      LOG.debug("Found classloader " + cl + " for " + pathStr);
      return cl;
    }

    if (path.getFileSystem(conf).isFile(path) && !pathStr.endsWith(".jar")) {
      throw new IOException(pathStr + ": not a jar file?");
    }

    Lock lock = locker.acquireLock(pathStr);
    try {
      cl = getIfCached(path);
      if (cl != null) {
        LOG.debug("Found classloader " + cl + " for " + pathStr);
        return cl;
      }

      cl = AccessController.doPrivileged(new PrivilegedAction<CoprocessorClassLoader>() {
        @Override
        public CoprocessorClassLoader run() {
          return new CoprocessorClassLoader(parent);
        }
      });

      cl.init(path, pathPrefix, conf);

      // Cache class loader as a weak value, will be GC'ed when no reference left
      CoprocessorClassLoader prev = classLoadersCache.putIfAbsent(path, cl);
      if (prev != null) {
        // Lost update race, use already added class loader
        LOG.warn("THIS SHOULD NOT HAPPEN, a class loader" + " is already cached for " + pathStr);
        cl = prev;
      }
      return cl;
    } finally {
      lock.unlock();
    }
  }
Get a CoprocessorClassLoader for a coprocessor jar path from cache. If not in cache, create
one.
@param path       the path to the coprocessor jar file to load classes from
@param parent     the parent class loader for exempted classes
@param pathPrefix a prefix used in temp path name to store the jar file locally
@param conf       the configuration used to create the class loader, if needed
@return a CoprocessorClassLoader for the coprocessor jar path
hbase-common/src/main/java/org/apache/hadoop/hbase/util/CoprocessorClassLoader.java