All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.edgar615.util.reflect.ClassLoaderChain Maven / Gradle / Ivy

The newest version!
package com.github.edgar615.util.reflect;

import com.github.edgar615.util.collection.CompoundEnumeration;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Chains multiple class loaders.
 *
 * @author [email protected]
 */
public class ClassLoaderChain extends ClassLoader {

  public static final Logger log = LoggerFactory.getLogger(ClassLoaderChain.class.getName());

  private final Collection classLoaders;

  private ClassLoaderChain(Collection classLoaders) {
    this.classLoaders = classLoaders;
  }

  /**
   * Creates a chain of class loaders. Handles null properly. This will create a new
   * chain, even if there is only one classloader in the chain. The usage for this is that
   * ResourceBundle caches resource per classloader.
   *
   * @return a class loader (never null)
   */
  public static ClassLoader createNewChain(ClassLoader... classLoaders) {
    return createChain(Arrays.asList(classLoaders), true);
  }

  /**
   * Creates a chain of class loaders. Handles null properly.
   *
   * @return a class loader (never null)
   */
  public static ClassLoader createChain(ClassLoader... classLoaders) {
    return createChain(Arrays.asList(classLoaders), false);
  }

  /**
   * Creates a chain of class loaders. Handles null properly.
   *
   * @return a class loader (never null)
   */
  public static ClassLoader createChain(List classLoaders) {
    return createChain(classLoaders, false);
  }

  /**
   * Creates a chain of class loaders. Handles null properly.
   *
   * @param createNew whether to create new instance of classloaderchain even if there is only one
   * loader
   * @return a class loader (never null)
   */
  public static ClassLoader createChain(List classLoaders, Boolean createNew) {
    List list = new ArrayList(classLoaders.size());
    for (ClassLoader classLoader : classLoaders) {
// we skip null class loaders
      if (classLoader == null) {
        continue;
      }
// we skip null class loaders
      if (classLoader instanceof NullClassLoader) {
        continue;
      }
// we 'flatten' the chain... no need to have a chain of a chain...
      if (classLoader instanceof ClassLoaderChain) {
        ClassLoaderChain classLoaderChain = (ClassLoaderChain) classLoader;
        list.addAll(classLoaderChain.classLoaders);
      } else {
        list.add(classLoader);
      }
    }
    if (list.size() == 0) {
      return NullClassLoader.instance();
    }
// remove duplicates
    ClassLoader previous = null;
    Iterator iter = list.iterator();
    while (iter.hasNext()) {
      ClassLoader next = iter.next();
      if (next.equals(previous)) {
        iter.remove();
      }
      previous = next;
    }
//TODO: create a new entry point, and keeping old behavior unchanged.
    if (list.size() == 1 && !createNew) {
      return list.get(0);
    }
    return new ClassLoaderChain(list);
  }

  @Override
  public Class loadClass(String name) throws ClassNotFoundException {
    Class clazz = null;
    for (ClassLoader classLoader : classLoaders) {
      try {
        clazz = classLoader.loadClass(name);
        return clazz;
      } catch (ClassNotFoundException e) {
        log.debug("class not found in " + classLoader + "... moving to next one");
      }
    }
    throw new ClassNotFoundException(name);
  }

  @Override
  public URL getResource(String name) {
    URL url = null;
    for (ClassLoader classLoader : classLoaders) {
      url = classLoader.getResource(name);
      if (url != null) {
        return url;
      }
    }
    return url;
  }

  @Override
  @SuppressWarnings("unchecked")
  public Enumeration getResources(String name) throws IOException {
    Enumeration[] enums = new Enumeration[classLoaders.size()];
    int i = 0;
    for (ClassLoader classLoader : classLoaders) {
      enums[i++] = classLoader.getResources(name);
    }
    return new CompoundEnumeration(enums);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy