Java/Reflection/ClassLoader

Материал из Java эксперт
Перейти к: навигация, поиск

A class loader which loads classes using a searchlist of other classloaders

    

/*
 * SearchlistClassLoader: class loader which loads classes using a searchlist
 *
 * Copyright (C) 2007-2009 Nik Trevallyn-Jones, Sydney Austraila.
 *
 * Author: Nik Trevallyn-Jones, nik777@users.sourceforge.net
 * $Id: Exp $
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See version 2 of the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * with this program. If not, version 2 of the license is available
 * from the GNU project, at http://www.gnu.org.
 */
/*
 * History:
 *   V1.2 NTJ, Jan 2009.
 *    - Fixed NullPointerException when searchlist was empty.
 *    - Added support for findLibrary()
 *
 *   V1.1 NTJ, Aug 2007.
 *    - Reworked the searchlist storage, and moved searchlist
 *      traversal into a new method: getLoader(int, byte).
 *      -- traversal should be somewhat faster; searchMode can be
 *         changed even after ClassLoaders have been added;
 *    - Reworked findClass(name) so that all classes located
 *      through shared loaders are associated with the shared
 *      loader, and all classes located through non-shared loaders
 *      are associated with the owning SearchlistClassLoader.
 *    - removed "recent" loader code.
 *
 *  V1.0  NTJ, April 2007.
 *    - Initial coding, based on a RemoteClassLoader used in AOS.
 */
import java.util.ArrayList;
import java.util.Vector;
import java.util.Hashtable;
import java.net.URL;
import java.net.URLClassLoader;
import java.io.*;
/**
 *  A class loader which loads classes using a searchlist of
 *  other classloaders.
 *
 *<br>The classloaders in the searchlist are of two types: <b>shared</b> and
 *  <b>non-shared</b>. A shared classloader may be in use by other code, and
 *  so <i>no</i> duplicates should be made of the classes in the loaders.
 *<br>A non-shared classloader is private to this SearchlistClassLoader, and
 *  so there is no possibility that other code could be using them. To avoid
 *  problems of isolation, all classes loaded through non-shared loaders are
 *  defined as having been loaded by the SearchlistClassLoader itself. This
 *  ensures the JVM can find the correct loader when loading associated
 *  classes (including shared classes).
 *
 *<br>The SearchlistClassLoader API therefore makes a clear distinction
 *  between <b>shared</b> and <b>non-shared</b> classloaders.
 *<br>The {@link #add(ClassLoader)} method adds an <i>existing</i> classloader
 *  which means the added classloader is treated as being <i>shared</i>.
 *<br>The {@link #add(URL)} method adds a new internally created classloader
 *  which loads the content associated with the specified URL, which means the
 *  internally created classloader is <i>non-shared</i>.
 *<br>
 *
 *<br>SearchlistClassLoader therefore also allows control over the order in
 *  which classloaders are searched, through the {@link #setSearchMode(byte)}
 *  method.
 *
 *<br>The possible <i>searchmodes</i> are:
 *<ul>
 *   <li>SHARED
 *  <br>added classloaders are searched before added URLs, which causes
 *  an existing class instance to be used (and SHARED) in preference to
 *  loading (or creating) a NON-SHARED duplicate.
 *
 *   <li>NONSHARED
 *  <br>added URLs are searched <i>before</i> added classloaders. This will
 *  create a NON-SHARED copy of a class (ie a duplicate) in preference to
 *  using a SHARED one from another classloader.
 *
 *   <li>ORDERED
 *  <br>added classloaders and URLs are searched in the order in which
 *  they were added to the searchlist.
 *</ul>
 *
 *<br>There is also a method which retrieves a class <i>without</i> searching
 *  any added classloaders. This effectively retrieves the <i>canonical</i>
 *  instance of the requested class (see {@link #loadLocalClass(String)}
 *  and {@link #getLocalResource(String)}).
 *
 *<p><i>Implementation notes:</i>.
 *
 *<br>Because each class object is associated with the classloader which
 *  defined it (see ClassLoader.defineClass(...)), SearchlistClassLoader
 *  must associate <i>itself</i> with <i>all</i> class objects it loads
 *  through <i>non-shared</i> loaders, and similarly <i>must not</i> associate
 *  itself with class objects loaded through shared loaders.
 *  (See {@link #findClass(String)}.)
 *
 *<br>The structure of the internal ClassLoader methods is as per the
 *  instructions in {@link java.lang.ClassLoader}. While I don"t think this is
 *  necessary any longer, it was quite easy to comply with the instructions.
 */
public class SearchlistClassLoader extends ClassLoader
{
    protected Vector list, search;
    protected Hashtable cache;
    protected Loader content = null;
    protected byte searchMode = SHARED;
    protected int divide = 0;
    /**  search mode enums  */
    public static final byte SHARED = 0x1;
    public static final byte NONSHARED  = 0x2;
    public static final byte ORDERED  = 0x3;
    protected static final URL EMPTY_URL[] = new URL[0];
    /**
     *  create a SearchlistClassLoader.
     */
    public SearchlistClassLoader()
    {}
    /**
     *  create a SearchlistClassLoader.
     */
    public SearchlistClassLoader(ClassLoader parent)
    { super(parent); }
    /**
     *  create a SearchlistClassLoader.
     */
    public SearchlistClassLoader(URL url[])
    { content = new Loader(new URLClassLoader(url), false); }
    /**
     *  create a SearchlistClassLoader.
     */
    public SearchlistClassLoader(URL url[], ClassLoader parent)
    {
  super(parent);
  content = new Loader(new URLClassLoader(url), false);
    }
    /**
     *  set the search mode.
     *
     *  @param mode enum for the searchmode: SHARED, NONSHARED, ORDERED
     */
    public void setSearchMode(byte mode)
    {
  byte prev = searchMode;
  searchMode = mode;
  if (searchMode <= 0 || searchMode > ORDERED) {
      System.out.println("SearchlistClassLoader.setSearchMode: " +
             "Invalid search mode: " + mode +
             "; defaulting to SHARED.");
      searchMode = SHARED;
  }
    }
    /**
     *  add a (shared) classloader to the searchlist.
     *
     *  The loader is added to the list as a shared loader.
     *
     *  @param loader the ClassLoader to add to the searchlist.
     */
    public void add(ClassLoader loader)
    {
  Loader ldr = new Loader(loader, true);
  // store loaders in order in list
  if (list == null) list = new Vector(16);
  list.add(ldr);
  // store shared loaders in front of non-shared loaders in search.
  if (search == null) search = new Vector(16);
  if (search.size() > divide) search.add(divide, ldr);
  else search.add(ldr);
  divide++;
    }
    /**
     *  add a (non-shared) URL to the searchlist.
     *
     *  Creates a new URLClassLoader and adds it to the searchlist as a
     *  non-shared classloader.
     *
     *  @param url the URL to add to the searchlist.
     */
    public void add(URL url)
    {
  Loader ldr = new Loader(new URLClassLoader(new URL[] { url }), false);
  // store loaders in order in list
  if (list == null) list = new Vector(16);
  list.add(ldr);
  // store non-shared loaders after shared loaders in search
  if (search == null) search = new Vector(16);
  search.add(ldr);
    }
    /**
     *  return the array of URLs used locally by this class loader
     */
    public URL[] getURLs()
    {
  return (content != null
    ? ((URLClassLoader)  content.loader).getURLs()
    : EMPTY_URL
    );
    }
    /**
     *  return the list of URLs in the search list
     */
    public URL[] getSearchPath()
    {
  Loader ldr;
  URL[] url;
  int j;
  ArrayList path = new ArrayList(8);
  for (int i = 0; (ldr = getLoader(i++, searchMode)) != null; i++) {
      if (ldr.loader instanceof SearchlistClassLoader)
    url = ((SearchlistClassLoader) ldr.loader).getSearchPath();
      else if (ldr.loader instanceof URLClassLoader)
    url = ((URLClassLoader) ldr.loader).getURLs();
      else
    url = null;
      if (url != null) {
    for (j = 0; j < url.length; j++)
        path.add(url[j]);
      }
  }
  return (path.size() > 0 ? (URL[]) path.toArray(EMPTY_URL) : EMPTY_URL);
    }
    /**
     *  Return the local class instance for <i>name</i>.
     *
     *<br>This does <i>not</i> search the searchlist. Only classes loaded
     *  directly by this loader or its parent are returned.
     *
     *<br>This method can be used to retrieve the <i>canonical</i> instance
     *  of a class.
     *  If this method is called on a set of SearchlistClassLoaders, then
     *  the only classloader which will return the class is the one which
     *  originally loaded it (assuming no duplicates have been created yet).
     *
     *  @param name the fully-qualified name of the class
     *  @return the loaded class.
     *
     *  @throws ClassNotFoundException if the class is not found.
     */
    public Class loadLocalClass(String name)
  throws ClassNotFoundException
    {
  ClassNotFoundException err = null;
  if (getParent() != null) {
      try {
    return getParent().loadClass(name);
      } catch (ClassNotFoundException e) {
    err = e;
      }
  }
  if (content != null) {
      // try the cache first
      Class result = (cache != null ? (Class) cache.get(name) : null);
      if (result != null) return result;
      // try loading the class data
      byte[] data = loadClassData(content.loader, name);
      if (data != null) {
    // define the class
    result = defineClass(name, data, 0, data.length);
    if (result != null) {
        //System.out.println("defined class: " + name);
        // cache the result
        if (cache == null) cache = new Hashtable(1024);
        cache.put(name, result);
        return result;
    }
      }
  }
  throw (err != null ? err : new ClassNotFoundException(name));
    }
    /**
     *  Return the URL for the local resource specified by <i>name</i>.
     *
     *<br>This does <i>not</i> search the searchlist. Only resources loaded
     *  directly by this loader or its parent are returned.
     *
     *<br>This method can be used to retrieve the <i>canonical</i> URL for a
     *  resource.
     *  If this method is called on a set of SearchlistClassLoaders, then
     *  the only classloader which will return the resource is the one which
     *  originally loaded it (assuming no duplicates have been created yet).
     *
     *  @param name the fully-qualified name of the resource.
     *  @return the located URL, or <i>null</i>.
     */
    public URL getLocalResource(String name)
    {
  URL result = null;
  if (getParent() != null) {
      result = getParent().getResource(name);
  }
  if (result == null && content != null) {
      result = content.loader.getResource(name);
  }
  return result;
    }

    /**
     *  Return a Class object for the specified class name.
     *
     *  @overloads java.lang.ClassLoader#findClass(String)
     *
     *  Traverses the searchlist looking for a classloader which can return
     *  the specified class.
     *
     *<br>This method is called by inherited loadClass() methods whenever
     *  a class cannot be found in the parent classloader.
     *
     *<br>If the class is found using a <i>shared</i> loader, then it is
     *  returned directly. If the class is found using a <i>non-shared</i>
     *  loader, then the actual class object is defined by the containing
     *  SearchlistClassLoader, which causes Java to associate the new class
     *  object with the SearchlistClassLaoder, rather then the non-shared
     *  loader.
     *
     *  @param name the fully-qualified name of the class
     *  @return the loaded class object
     *
     *  @throws ClassNotFoundException if the class could not be loaded.
     */
    public Class findClass(String name)
  throws ClassNotFoundException
    {
  Loader ldr;
  Throwable err = null;
  Class result;
  byte[] data;
  for (int i = 0; (ldr = getLoader(i, searchMode)) != null; i++) {
      try {
    // for shared loaders - just try getting the class
    if (ldr.shared)
        return ldr.loader.loadClass(name);
    // for non-shared loaders, we have to define the class manually
    else {
        // check the cache first
        result = (cache != null ? (Class) cache.get(name) : null);
        if (result != null) return result;
        // try loading the class
        data = loadClassData(ldr.loader, name);
        if (data != null) {
      // data loaded, define the class
      result = defineClass(name, data, 0, data.length);
      if (result != null) {
          //System.out.println("defined class: " + name);
          // cache the result
          if (cache == null) cache = new Hashtable(1024);
          cache.put(name, result);
          return result;
      }
        }
    }
      }
      catch (Throwable t) {
    err = t;
      }
  }
  throw (err != null
       ? new ClassNotFoundException(name, err)
       : new ClassNotFoundException(name)
       );
    }
    /**
     *  find a resource using the searchlist.
     *
     *  @overloads ClassLoader#findResource(String)
     *
     *  <em>Note</em>Inherited behaviour of loadClass() and getResource() means
     *  that this method is <em>not</em> called if our parent classloader has
     *  already found the data.
     *
     *  @param path the fully-qualified name of the resource to retrieve
     *  @return the URL if the resource is found, and <i>null</i> otherwise.
     */
    public URL findResource(String path)
    {
  System.out.println("findResource: looking in " + this + " for " +
         path);
  URL url = null;
  Loader ldr;
  for (int i = 0; (ldr = getLoader(i, searchMode)) != null; i++) {
      url = ldr.loader.getResource(path);
      if (url != null) {
    System.out.println("found " + path + " in loader: " +
           ldr.loader);
    break;
      }
  }
  return url;
    }
    /**
     *  return the pathname to the specified native library.
     *
     *  If the library is not found on the searchpath, then <i>null</i>
     *  is returned, indicating to the Java machine that it should search
     *  java.library.path.
     *
     *  @param libname - the String name of the library to find
     *  @return the full path to the found library file, or <i>null</i>.
     */
    public String findLibrary(String libname)
    {
  String fileName = System.mapLibraryName(libname);
  System.out.println("findLibrary: looking in " + this + " for " +
         libname + " as " + fileName);
  int i, j;
  URL[] url;
  File dir, file;
  Loader ldr;
  for (i = 0; (ldr = getLoader(i++, searchMode)) != null; i++) {
      if (ldr.loader instanceof SearchlistClassLoader)
    url = ((SearchlistClassLoader) ldr.loader).getSearchPath();
      else if (ldr.loader instanceof URLClassLoader)
    url = ((URLClassLoader) ldr.loader).getURLs();
      else
    url = null;
      if (url != null) {
    for (j = 0; j < url.length; j++) {
        if (!url[j].getProtocol().equalsIgnoreCase("file"))
      continue;
        
        try {
      dir = new File(url[j].toURI()).getParentFile();
      file = new File(dir, fileName);
      if (file.exists()) {
          System.out.println("found: " +
                 file.getAbsolutePath());
          return file.getAbsolutePath();
      }
        } catch (Exception e) {
      System.out.println("Ignoring url: " + url[j] + ": "
             + e);
        }
    }
      }
  }
  // nothing found, use java.library.path
  return null;
    }
    /**
     *  return the correct classloader for the specified position in the
     *  search.
     *
     *  @param index the position (step) in the search process
     *  @param mode the search mode to use
     *
     *  @return The corresponding Loader or <i>null</i>
     */
    protected Loader getLoader(int index, byte mode)
    {
  // content is always the first loader searched
  if (content != null) {
      if (index == 0) return content;
      else index--;
  }
  if (index < 0 || list == null || index >= list.size()) return null;
  Loader result;
  switch (mode) {
  case SHARED:
      // return shared loaders before non-shared loaders
      result = (Loader) search.get(index);
      break;
  case NONSHARED:
      // return non-shared loaders before shared loaders
      {
    int pos = index + divide;
    result = (Loader) (pos < search.size()
          ? search.get(pos)
          : search.get(pos-divide)
          );
      }
      break;
  default:
      // return loaders in the order in which they were added
      result = (Loader) list.get(index);
  }
  return result;
    }
    /**
     *  load the byte data for a class definition.
     *
     *  @param name the fully-qualified class name
     *  @return a byte[] containing the class bytecode or <i>null</i>
     */
    protected byte[] loadClassData(ClassLoader cl, String name)
    {
  ByteArrayOutputStream barray;
  byte buff[];
  int len;
  InputStream in = cl.getResourceAsStream(translate(name, ".", "/")
            + ".class");
  if (in == null) return null;
  try {
      
      barray = new ByteArrayOutputStream(1024*16);
      buff = new byte[1024];
      do {
    len = in.read(buff, 0, buff.length);
    if (len > 0) barray.write(buff, 0, len);
      } while (len >= 0);
      return (barray.size() > 0 ? barray.toByteArray() : null);
  } catch (Exception e) {
      return null;
  }
    }

    /**
     *  translate matching chars in a string.
     *
     *  @param str the String to translate
     *  @param match the list of chars to match, in a string.
     *  @param replace the list of corresponding chars to replace matched chars
     *    with.
     *
     *<pre>
     *  Eg: translate("the dog.", "o.", "i")
     *  returns "the dig", because "o" is replaced with "i", and "." is
     *  replaced with nothing (ie deleted).
     *</pre>
     *
     *  @return the result as a string.
     */
    public static String translate(String str, String match, String replace)
    {
  StringBuffer b = new StringBuffer(str.length());
  int pos = 0;
  char c = 0;
  if (match == null) match = "";
  if (replace == null) replace = "";
  boolean copy = (match.length() != 0 &&
      match.length() >= replace.length());
  // loop over the input string
  int max = str.length();
  for (int x = 0; x < max; x++) {
      c = str.charAt(x);
      pos = match.indexOf(c);
      // if found c in "match"
      if (pos >= 0) {
    // translate
    if (pos < replace.length()) b.append(replace.charAt(pos));
      }
      // copy
      else if (copy || replace.indexOf(c) >= match.length()) b.append(c);
      // otherwise, effectively, delete...
  }
  
  return b.toString();
    }
    /**
     *  internal class to store the state of each searchable ClassLoader.
     *
     *  The containing SearchlistClassLoader needs to know information about
     *  each loader in the list.
     */
    protected static class Loader
    {
  ClassLoader loader = null;    // the actual classloader
  boolean shared = false;     // shared flag
  Loader(ClassLoader loader, boolean shared)
  {
      this.loader = loader;
      this.shared = shared;
  }
    }
}





A class to simplify access to resources through the classloader

  
/*
 *  Copyright 2004 Clinton Begin
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.Properties;
/**
 * A class to simplify access to resources through the classloader.
 */
public class Resources extends Object {
  private static ClassLoader defaultClassLoader;
  
  /**
   * Charset to use when calling getResourceAsReader.
   * null means use the system default.
   */
  private static Charset charset;
  private Resources() {
  }
  /**
   * Returns the default classloader (may be null).
   *
   * @return The default classloader
   */
  public static ClassLoader getDefaultClassLoader() {
    return defaultClassLoader;
  }
  /**
   * Sets the default classloader
   *
   * @param defaultClassLoader - the new default ClassLoader
   */
  public static void setDefaultClassLoader(ClassLoader defaultClassLoader) {
    Resources.defaultClassLoader = defaultClassLoader;
  }
  /**
   * Returns the URL of the resource on the classpath
   *
   * @param resource The resource to find
   * @return The resource
   * @throws IOException If the resource cannot be found or read
   */
  public static URL getResourceURL(String resource) throws IOException {
    return getResourceURL(getClassLoader(), resource);
  }
  /**
   * Returns the URL of the resource on the classpath
   *
   * @param loader   The classloader used to load the resource
   * @param resource The resource to find
   * @return The resource
   * @throws IOException If the resource cannot be found or read
   */
  public static URL getResourceURL(ClassLoader loader, String resource) throws IOException {
    URL url = null;
    if (loader != null) url = loader.getResource(resource);
    if (url == null) url = ClassLoader.getSystemResource(resource);
    if (url == null) throw new IOException("Could not find resource " + resource);
    return url;
  }
  /**
   * Returns a resource on the classpath as a Stream object
   *
   * @param resource The resource to find
   * @return The resource
   * @throws IOException If the resource cannot be found or read
   */
  public static InputStream getResourceAsStream(String resource) throws IOException {
    return getResourceAsStream(getClassLoader(), resource);
  }
  /**
   * Returns a resource on the classpath as a Stream object
   *
   * @param loader   The classloader used to load the resource
   * @param resource The resource to find
   * @return The resource
   * @throws IOException If the resource cannot be found or read
   */
  public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
    InputStream in = null;
    if (loader != null) in = loader.getResourceAsStream(resource);
    if (in == null) in = ClassLoader.getSystemResourceAsStream(resource);
    if (in == null) throw new IOException("Could not find resource " + resource);
    return in;
  }
  /**
   * Returns a resource on the classpath as a Properties object
   *
   * @param resource The resource to find
   * @return The resource
   * @throws IOException If the resource cannot be found or read
   */
  public static Properties getResourceAsProperties(String resource)
      throws IOException {
    Properties props = new Properties();
    InputStream in = null;
    String propfile = resource;
    in = getResourceAsStream(propfile);
    props.load(in);
    in.close();
    return props;
  }
  /**
   * Returns a resource on the classpath as a Properties object
   *
   * @param loader   The classloader used to load the resource
   * @param resource The resource to find
   * @return The resource
   * @throws IOException If the resource cannot be found or read
   */
  public static Properties getResourceAsProperties(ClassLoader loader, String resource)
      throws IOException {
    Properties props = new Properties();
    InputStream in = null;
    String propfile = resource;
    in = getResourceAsStream(loader, propfile);
    props.load(in);
    in.close();
    return props;
  }
  /**
   * Returns a resource on the classpath as a Reader object
   *
   * @param resource The resource to find
   * @return The resource
   * @throws IOException If the resource cannot be found or read
   */
  public static Reader getResourceAsReader(String resource) throws IOException {
    Reader reader;
    if (charset == null) {
      reader = new InputStreamReader(getResourceAsStream(resource));
    } else {
      reader = new InputStreamReader(getResourceAsStream(resource), charset);
    }
    
    return reader;
  }
  /**
   * Returns a resource on the classpath as a Reader object
   *
   * @param loader   The classloader used to load the resource
   * @param resource The resource to find
   * @return The resource
   * @throws IOException If the resource cannot be found or read
   */
  public static Reader getResourceAsReader(ClassLoader loader, String resource) throws IOException {
    Reader reader;
    if (charset == null) {
      reader = new InputStreamReader(getResourceAsStream(loader, resource));
    } else {
      reader = new InputStreamReader(getResourceAsStream(loader, resource), charset);
    }
    
    return reader;
  }
  /**
   * Returns a resource on the classpath as a File object
   *
   * @param resource The resource to find
   * @return The resource
   * @throws IOException If the resource cannot be found or read
   */
  public static File getResourceAsFile(String resource) throws IOException {
    return new File(getResourceURL(resource).getFile());
  }
  /**
   * Returns a resource on the classpath as a File object
   *
   * @param loader   - the classloader used to load the resource
   * @param resource - the resource to find
   * @return The resource
   * @throws IOException If the resource cannot be found or read
   */
  public static File getResourceAsFile(ClassLoader loader, String resource) throws IOException {
    return new File(getResourceURL(loader, resource).getFile());
  }
  /**
   * Gets a URL as an input stream
   *
   * @param urlString - the URL to get
   * @return An input stream with the data from the URL
   * @throws IOException If the resource cannot be found or read
   */
  public static InputStream getUrlAsStream(String urlString) throws IOException {
    URL url = new URL(urlString);
    URLConnection conn = url.openConnection();
    return conn.getInputStream();
  }
  /**
   * Gets a URL as a Reader
   *
   * @param urlString - the URL to get
   * @return A Reader with the data from the URL
   * @throws IOException If the resource cannot be found or read
   */
  public static Reader getUrlAsReader(String urlString) throws IOException {
    return new InputStreamReader(getUrlAsStream(urlString));
  }
  /**
   * Gets a URL as a Properties object
   *
   * @param urlString - the URL to get
   * @return A Properties object with the data from the URL
   * @throws IOException If the resource cannot be found or read
   */
  public static Properties getUrlAsProperties(String urlString) throws IOException {
    Properties props = new Properties();
    InputStream in = null;
    String propfile = urlString;
    in = getUrlAsStream(propfile);
    props.load(in);
    in.close();
    return props;
  }
  /**
   * Loads a class
   *
   * @param className - the class to load
   * @return The loaded class
   * @throws ClassNotFoundException If the class cannot be found (duh!)
   */
  public static Class classForName(String className) throws ClassNotFoundException {
    Class clazz = null;
    try {
      clazz = getClassLoader().loadClass(className);
    } catch (Exception e) {
      // Ignore.  Failsafe below.
    }
    if (clazz == null) {
      clazz = Class.forName(className);
    }
    return clazz;
  }
  /**
   * Creates an instance of a class
   *
   * @param className - the class to create
   * @return An instance of the class
   * @throws ClassNotFoundException If the class cannot be found (duh!)
   * @throws InstantiationException If the class cannot be instantiaed
   * @throws IllegalAccessException If the class is not public, or other access problems arise
   */
  public static Object instantiate(String className)
      throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    return instantiate(classForName(className));
  }
  /**
   * Creates an instance of a class
   *
   * @param clazz - the class to create
   * @return An instance of the class
   * @throws InstantiationException If the class cannot be instantiaed
   * @throws IllegalAccessException If the class is not public, or other access problems arise
   */
  public static Object instantiate(Class clazz) throws InstantiationException, IllegalAccessException {
    try {
      return clazz.newInstance();
    } catch (Exception e) {
      // Try alternative...theoretically should fail for the exact same
      // reason, but in case of a weird security manager, this will help
      // some cases.
      //return clazz.newInstance();
      return clazz.newInstance();
    }
  }
  private static ClassLoader getClassLoader() {
    if (defaultClassLoader != null) {
      return defaultClassLoader;
    } else {
      return Thread.currentThread().getContextClassLoader();
    }
  }
  public static Charset getCharset() {
    return charset;
  }
  /**
   * Use this method to set the Charset to be used when
   * calling the getResourceAsReader methods.  This will
   * allow iBATIS to function properly when the system default
   * encoding doesn"t deal well with unicode (IBATIS-340, IBATIS-349)
   * 
   * @param charset
   */
  public static void setCharset(Charset charset) {
    Resources.charset = charset;
  }
}





Analyze ClassLoader hierarchy for any given object or class loader

    
/*
 * Copyright 2002-2005 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Utility class for diagnostic purposes, to analyze the
 * ClassLoader hierarchy for any given object or class loader.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @since 02 April 2001
 * @see java.lang.ClassLoader
 */
public abstract class ClassLoaderUtils {
  /**
   * Show the class loader hierarchy for this class.
   * Uses default line break and tab text characters.
   * @param obj object to analyze loader hierarchy for
   * @param role a description of the role of this class in the application
   * (e.g., "servlet" or "EJB reference")
   * @return a String showing the class loader hierarchy for this class
   */
  public static String showClassLoaderHierarchy(Object obj, String role) {
    return showClassLoaderHierarchy(obj, role, "\n", "\t");
  }
  /**
   * Show the class loader hierarchy for this class.
   * @param obj object to analyze loader hierarchy for
   * @param role a description of the role of this class in the application
   * (e.g., "servlet" or "EJB reference")
   * @param lineBreak line break
   * @param tabText text to use to set tabs
   * @return a String showing the class loader hierarchy for this class
   */
  public static String showClassLoaderHierarchy(Object obj, String role, String lineBreak, String tabText) {
    String s = "object of " + obj.getClass() + ": role is " + role + lineBreak;
    return s + showClassLoaderHierarchy(obj.getClass().getClassLoader(), lineBreak, tabText, 0);
  }
  /**
   * Show the class loader hierarchy for the given class loader.
   * Uses default line break and tab text characters.
   * @param cl class loader to analyze hierarchy for
   * @return a String showing the class loader hierarchy for this class
   */
  public static String showClassLoaderHierarchy(ClassLoader cl) {
    return showClassLoaderHierarchy(cl, "\n", "\t");
  }
  /**
   * Show the class loader hierarchy for the given class loader.
   * @param cl class loader to analyze hierarchy for
   * @param lineBreak line break
   * @param tabText text to use to set tabs
   * @return a String showing the class loader hierarchy for this class
   */
  public static String showClassLoaderHierarchy(ClassLoader cl, String lineBreak, String tabText) {
    return showClassLoaderHierarchy(cl, lineBreak, tabText, 0);
  }
  /**
   * Show the class loader hierarchy for the given class loader.
   * @param cl class loader to analyze hierarchy for
   * @param lineBreak line break
   * @param tabText text to use to set tabs
   * @param indent nesting level (from 0) of this loader; used in pretty printing
   * @return a String showing the class loader hierarchy for this class
   */
  private static String showClassLoaderHierarchy(ClassLoader cl, String lineBreak, String tabText, int indent) {
    if (cl == null) {
      ClassLoader ccl = Thread.currentThread().getContextClassLoader();
      return "context class loader=[" + ccl + "] hashCode=" + ccl.hashCode();
    }
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < indent; i++) {
      buf.append(tabText);
    }
    buf.append("[").append(cl).append("] hashCode=").append(cl.hashCode()).append(lineBreak);
    ClassLoader parent = cl.getParent();
    return buf.toString() + showClassLoaderHierarchy(parent, lineBreak, tabText, indent + 1);
  }
}





Class Finder

    
/*
 * Copyright 2007 (C) TJDO.
 * All rights reserved.
 *
 * This software is distributed under the terms of the TJDO License version 1.0.
 * See the terms of the TJDO License in the documentation provided with this software.
 *
 * $Id: ClassFinder.java,v 1.1 2007/10/03 01:20:37 jackknifebarber Exp $
 */

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

/**
 * Used to load classes according to the rules defined in the JDO spec.
 * See section 12.5 of the JDO 1.0.1 spec.
 * <p>
 * This class also provides a {@link #classForName(String,boolean,ClassLoader)
 * static method} for loading classes that utilizes a cache.
 * The cache contains class names that were previously <em>not</em> found,
 * organized by the loader that failed to find them.
 * This speeds up cases where attempts to load the same non-existent class are
 * repeated many times.
 *
 * @author 
 * @version $Revision: 1.1 $
 */
public class ClassFinder
{
    private static final Map findersByLoader = new WeakHashMap();
    private static final Map nonExistentClassNamesByLoader = new WeakHashMap();

    /**
     * Returns the class finder instance associated with the context class
     * loader of the calling thread.
     */
    public static ClassFinder getInstance()
    {
        return getInstance(getContextClassLoaderPrivileged());
    }
    /**
     * Returns the class finder instance associated with the specified class
     * loader.
     * The specified loader becomes the finder"s "original context class loader"
     * for the algorithm implemented by
     * {@link #classForName(String,boolean,Class)}.
     *
     * @param ctxLoader
     *      the context class loader
     */
    public static synchronized ClassFinder getInstance(ClassLoader ctxLoader)
    {
        ClassFinder cf = (ClassFinder)findersByLoader.get(ctxLoader);
        if (cf == null)
            findersByLoader.put(ctxLoader, cf = new ClassFinder(ctxLoader));
        return cf;
    }
    /**
     * Calls getContextClassLoader() for the current thread in a doPrivileged
     * block.
     *
     * @return
     *      The context class loader of the current thread.
     * @exception SecurityException
     *      If getContextClassLoader() fails.
     */
    private static ClassLoader getContextClassLoaderPrivileged() throws SecurityException
    {
        return (ClassLoader)AccessController.doPrivileged(
            new PrivilegedAction()
            {
                public Object run()
                {
                    return Thread.currentThread().getContextClassLoader();
                }
            }
        );
    }

    private final ClassLoader origContextClassLoader;
    private ClassFinder(ClassLoader origContextClassLoader)
    {
        this.origContextClassLoader = origContextClassLoader;
    }
    /**
     * Returns the <tt>Class</tt> object associated with the class or interface
     * with the given string name.
     * <p>
     * This method implements the algorithm described in section 12.5 of the JDO
     * 1.0.1 spec.
     * It attempts to load the class using up to three loaders:
     * <ol>
     *  <li>The loader that loaded the class or instance referred to in the API
     *  that caused this class to be loaded (the context class).</li>
     *  <li>The loader returned in the current context by
     *  <tt>Thread.getContextClassLoader()</tt>.</li>
     *  <li>The loader returned by <tt>Thread.getContextClassLoader()</tt> at
     *  the time this <tt>ClassFinder</tt> was constructed (which should equate
     *  to the time of <tt>PersistenceManagerFactory.getPersistenceManager()</tt>).
     *  </li>
     * </ol>
     *
     * @param className
     *      fully qualified name of the desired class
     * @param initialize
     *      whether the class must be initialized
     * @param contextClass
     *      another class to serve as context for the loading of the named
     *      class, or <code>null</code> if there is no such other class
     *
     * @return
     *      class object representing the desired class 
     * @exception ClassNotFoundException
     *      if the class cannot be located
     */
    public Class classForName(String className, boolean initialize, Class contextClass) throws ClassNotFoundException
    {
        if (contextClass != null)
        {
            try
            {
                return classForName(className, initialize, contextClass.getClassLoader());
            }
            catch (ClassNotFoundException e)
            {
            }
        }
        return classForName(className, initialize);
    }
    /**
     * Returns the <tt>Class</tt> object associated with the class or interface
     * with the given string name.
     * <p>
     * This method is equivalent to:
     * <blockquote><pre>
     * classForName(className, initialize, null)
     * </pre></blockquote>
     *
     * @param className
     *      fully qualified name of the desired class
     * @param initialize
     *      whether the class must be initialized
     *
     * @return
     *      class object representing the desired class 
     * @exception ClassNotFoundException
     *      if the class cannot be located
     */
    public Class classForName(String className, boolean initialize) throws ClassNotFoundException
    {
        try
        {
            return classForName(className, initialize, getContextClassLoaderPrivileged());
        }
        catch (ClassNotFoundException e)
        {
            return classForName(className, initialize, origContextClassLoader);
        }
    }
    /**
     * Returns the <tt>Class</tt> object associated with the class or interface
     * with the given string name.
     * <p>
     * This method is functionally equivalent to
     *{@link Class#forName(String,boolean,ClassLoader)}
     * except that it maintains a cache of class names that are <em>not</em>
     * found.
     * In many cases, especially in an app server environment, searching for
     * non-existent classes can be a slow process.
     * It"s important because some things in TJDO, notably the macro mechanism
     * used in e.g. view definitions, will search for class names that don"t
     * exist.
     *
     * @param className
     *      fully qualified name of the desired class
     * @param initialize
     *      whether the class must be initialized
     * @param loader
     *      class loader from which the class must be loaded 
     *
     * @return
     *      class object representing the desired class 
     * @exception ClassNotFoundException
     *      if the class cannot be located
     */
    public static Class classForName(String className, boolean initialize, ClassLoader loader) throws ClassNotFoundException
    {
        Set names;
        synchronized (nonExistentClassNamesByLoader)
        {
            names = (Set)nonExistentClassNamesByLoader.get(loader);
            if (names == null)
                nonExistentClassNamesByLoader.put(loader, names = new HashSet());
            else
            {
                if (names.contains(className))
                    throw new ClassNotFoundException(className + " (cached from previous lookup attempt)");
            }
        }
        try
        {
            return Class.forName(className, initialize, loader);
        }
        catch (ClassNotFoundException e)
        {
           
            synchronized (nonExistentClassNamesByLoader) { names.add(className); }
            throw e;
        }
    }
    /**
     * Returns a hash code value for this object.
     */
    public int hashCode()
    {
        return origContextClassLoader.hashCode();
    }
    /**
     * Indicates whether some object is "equal to" this one.
     * Two <tt>ClassFinder</tt> objects are considered equal if their original
     * context class loaders are all equal.
     *
     * @param obj
     *      the reference object with which to compare
     *
     * @return
     *      <tt>true</tt> if this object is equal to the obj argument;
     *      <tt>false</tt> otherwise.
     */
    public boolean equals(Object obj)
    {
        if (obj == this)
            return true;
        if (!(obj instanceof ClassFinder))
            return false;
        ClassFinder cf = (ClassFinder)obj;
        return origContextClassLoader.equals(cf.origContextClassLoader);
    }
}





Class For Name

    
// $Id: ReflectionHelper.java 16271 2009-04-07 20:20:12Z hardy.ferentschik $
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,  
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
 * Some reflection utility methods.
 *
 * @author Hardy Ferentschik
 */
public class ReflectionHelper {

  public static Class<?> classForName(String name, Class<?> caller) throws ClassNotFoundException {
    try {
      ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
      if ( contextClassLoader != null ) {
        return contextClassLoader.loadClass( name );
      }
    }
    catch ( Throwable e ) {
      // ignore
    }
    return Class.forName( name, true, caller.getClassLoader() );
  }
}





Context ClassLoader

    
/**************************************************************************************
 * Copyright (c) Jonas Bon�r, Alexandre Vasseur. All rights reserved.                 *
 * http://aspectwerkz.codehaus.org                                                    *
 * ---------------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the LGPL license      *
 * a copy of which has been included with this distribution in the license.txt file.  *
 **************************************************************************************/

import java.io.InputStream;
import java.net.URL;
/**
 * Utility methods dealing with the context class loader. Fail-over is provided to the default class loader.
 *
 * @author 
 */
public final class ContextClassLoader {
    /**
     * Loads a class starting from the given class loader (can be null, then use default class loader)
     *
     * @param loader
     * @param name   of class to load
     * @return
     * @throws ClassNotFoundException
     */
    public static Class forName(final ClassLoader loader, final String name) throws ClassNotFoundException {
        Class klass = null;
        if (loader != null) {
            klass = Class.forName(name, false, loader);
        } else {
            klass = Class.forName(name, false, ClassLoader.getSystemClassLoader());
        }
        return klass;
    }

    /**
     * Loads a class from the context class loader or, if that fails, from the default class loader.
     *
     * @param name is the name of the class to load.
     * @return a <code>Class</code> object.
     * @throws ClassNotFoundException if the class was not found.
     */
    public static Class forName(final String name) throws ClassNotFoundException {
        Class cls = null;
        try {
            cls = Class.forName(name, false, Thread.currentThread().getContextClassLoader());
        } catch (Exception e) {
            cls = Class.forName(name);
        }
        return cls;
    }
    /**
     * Loads a resource from the context class loader or, if that fails, from the default class loader.
     *
     * @param name is the name of the resource to load.
     * @return a <code>URL</code> object.
     */
    public static URL loadResource(final String name) {
        try {
            return Thread.currentThread().getContextClassLoader().getResource(name);
        } catch (Exception e) {
            return ClassLoader.class.getClassLoader().getResource(name);
        }
    }
//    /**
//     * Loads a resource from the context class loader or, if that fails, from the default class loader, as stream
//     *
//     * @param name is the name of the resource to load.
//     * @return a <code>InputStream</code> object.
//     */
//    public static InputStream getResourceAsStream(final String name) {
//        InputStream stream = null;
//        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
//        if (contextClassLoader != null) {
//            stream = contextClassLoader.getResourceAsStream(name);
//        }
//        if (stream == null) {
//            ClassLoader classLoader = ClassLoader.class.getClassLoader();
//            if (classLoader != null) {
//                stream = classLoader.getResourceAsStream(name);
//            }
//        }
//        return stream;
//    }
    /**
     * Returns the context class loader.
     *
     * @return the context class loader
     */
    public static ClassLoader getLoader() {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        if (loader == null) {
            loader = ClassLoader.class.getClassLoader();
        }
        return loader;
    }
}





Determining from Where a Class Was Loaded

       
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
public class Main {
  public Main() {
    Class cls = this.getClass();
    ProtectionDomain pDomain = cls.getProtectionDomain();
    CodeSource cSource = pDomain.getCodeSource();
    URL loc = cSource.getLocation();
  }
  public static void main(String[] argv) throws Exception {
  }
}





does Class Exist

  
public class Main {
  public static boolean doesClassExist(String name) {
    try {
      Class c = Class.forName(name);
      if (c != null)
        return true;
    } catch (ClassNotFoundException e) {
      // Class not found
    } catch (Exception e) {
      e.printStackTrace();
    }
    return false;
  }
}





Dynamically Reloading a Modified Class

       
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
class MyClass{
  public String myMethod() {
    return "a message";
  }
}
public class Main {
  public static void main(String[] argv) throws Exception {
    URL[] urls = null;
    File dir = new File(System.getProperty("user.dir") + File.separator + "dir" + File.separator);
    URL url = dir.toURI().toURL();
    urls = new URL[] { url };
    ClassLoader cl = new URLClassLoader(urls);
    Class cls = cl.loadClass("MyClass");
    MyClass myObj = (MyClass) cls.newInstance();
  }
}





Equivalently to invoking Thread.currentThread().getContextClassLoader().loadClass(className); but it supports primitive types and array classes of object types or primitive types.

   
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
import java.lang.reflect.Array;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
/**
 * A collection of <code>Class</code> utilities.
 * 
 * @version <tt>$Revision: 2787 $</tt>
 * @author 
 * @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis<a/>
 */
@SuppressWarnings("unchecked")
public final class Classes {
  /** The string used to separator packages */
  public static final String PACKAGE_SEPARATOR = ".";
  /** The characther used to separator packages */
  public static final char PACKAGE_SEPARATOR_CHAR = ".";
  /** The default package name. */
  public static final String DEFAULT_PACKAGE_NAME = "<default>";

  /**
   * Describe the class of an object
   * 
   * @param object
   *          the object
   * @return the description
   */
  public static String getDescription(Object object) {
    StringBuffer buffer = new StringBuffer();
    describe(buffer, object);
    return buffer.toString();
  }
  /**
   * Describe the class of an object
   * 
   * @param buffer
   *          the string buffer
   * @param object
   *          the object
   */
  public static void describe(StringBuffer buffer, Object object) {
    if (object == null)
      buffer.append("**null**");
    else
      describe(buffer, object.getClass());
  }
  /**
   * Describe the class
   * 
   * @param buffer
   *          the string buffer
   * @param clazz
   *          the clazz
   */
  public static void describe(StringBuffer buffer, Class clazz) {
    if (clazz == null)
      buffer.append("**null**");
    else {
      buffer.append("{class=").append(clazz.getName());
      Class[] intfs = clazz.getInterfaces();
      if (intfs.length > 0) {
        buffer.append(" intfs=");
        for (int i = 0; i < intfs.length; ++i) {
          buffer.append(intfs[i].getName());
          if (i < intfs.length - 1)
            buffer.append(", ");
        }
      }
      buffer.append("}");
    }
  }
  /**
   * Get the short name of the specified class by striping off the package name.
   * 
   * @param classname
   *          Class name.
   * @return Short class name.
   */
  public static String stripPackageName(final String classname) {
    int idx = classname.lastIndexOf(PACKAGE_SEPARATOR);
    if (idx != -1)
      return classname.substring(idx + 1, classname.length());
    return classname;
  }
  /**
   * Get the short name of the specified class by striping off the package name.
   * 
   * @param type
   *          Class name.
   * @return Short class name.
   */
  public static String stripPackageName(final Class type) {
    return stripPackageName(type.getName());
  }
  /**
   * Get the package name of the specified class.
   * 
   * @param classname
   *          Class name.
   * @return Package name or "" if the classname is in the <i>default</i>
   *         package.
   * 
   * @throws EmptyStringException
   *           Classname is an empty string.
   */
  public static String getPackageName(final String classname) {
    if (classname.length() == 0)
      System.out.println("Empty String Exception");
    int index = classname.lastIndexOf(PACKAGE_SEPARATOR);
    if (index != -1)
      return classname.substring(0, index);
    return "";
  }
  /**
   * Get the package name of the specified class.
   * 
   * @param type
   *          Class.
   * @return Package name.
   */
  public static String getPackageName(final Class type) {
    return getPackageName(type.getName());
  }

  // ///////////////////////////////////////////////////////////////////////
  // Primitives //
  // ///////////////////////////////////////////////////////////////////////
  /** Primitive type name -> class map. */
  private static final Map PRIMITIVE_NAME_TYPE_MAP = new HashMap();
  /** Setup the primitives map. */
  static {
    PRIMITIVE_NAME_TYPE_MAP.put("boolean", Boolean.TYPE);
    PRIMITIVE_NAME_TYPE_MAP.put("byte", Byte.TYPE);
    PRIMITIVE_NAME_TYPE_MAP.put("char", Character.TYPE);
    PRIMITIVE_NAME_TYPE_MAP.put("short", Short.TYPE);
    PRIMITIVE_NAME_TYPE_MAP.put("int", Integer.TYPE);
    PRIMITIVE_NAME_TYPE_MAP.put("long", Long.TYPE);
    PRIMITIVE_NAME_TYPE_MAP.put("float", Float.TYPE);
    PRIMITIVE_NAME_TYPE_MAP.put("double", Double.TYPE);
  }
  /**
   * Get the primitive type for the given primitive name.
   * 
   * <p>
   * For example, "boolean" returns Boolean.TYPE and so on...
   * 
   * @param name
   *          Primitive type name (boolean, int, byte, ...)
   * @return Primitive type or null.
   * 
   * @exception IllegalArgumentException
   *              Type is not a primitive class
   */
  public static Class getPrimitiveTypeForName(final String name) {
    return (Class) PRIMITIVE_NAME_TYPE_MAP.get(name);
  }
  /** Map of primitive types to their wrapper classes */
  private static final Class[] PRIMITIVE_WRAPPER_MAP = { Boolean.TYPE, Boolean.class, Byte.TYPE,
      Byte.class, Character.TYPE, Character.class, Double.TYPE, Double.class, Float.TYPE,
      Float.class, Integer.TYPE, Integer.class, Long.TYPE, Long.class, Short.TYPE, Short.class, };
  /**
   * Get the wrapper class for the given primitive type.
   * 
   * @param type
   *          Primitive class.
   * @return Wrapper class for primitive.
   * 
   * @exception IllegalArgumentException
   *              Type is not a primitive class
   */
  public static Class getPrimitiveWrapper(final Class type) {
    if (!type.isPrimitive()) {
      throw new IllegalArgumentException("type is not a primitive class");
    }
    for (int i = 0; i < PRIMITIVE_WRAPPER_MAP.length; i += 2) {
      if (type.equals(PRIMITIVE_WRAPPER_MAP[i]))
        return PRIMITIVE_WRAPPER_MAP[i + 1];
    }
    // should never get here, if we do then PRIMITIVE_WRAPPER_MAP
    // needs to be updated to include the missing mapping
    System.out.println("Unreachable Statement Exception");
    return null;
  }

  /**
   * Check if the given class is a primitive wrapper class.
   * 
   * @param type
   *          Class to check.
   * @return True if the class is a primitive wrapper.
   */
  public static boolean isPrimitiveWrapper(final Class type) {
    for (int i = 0; i < PRIMITIVE_WRAPPER_MAP.length; i += 2) {
      if (type.equals(PRIMITIVE_WRAPPER_MAP[i + 1])) {
        return true;
      }
    }
    return false;
  }
  /**
   * Check if the given class is a primitive class or a primitive wrapper class.
   * 
   * @param type
   *          Class to check.
   * @return True if the class is a primitive or primitive wrapper.
   */
  public static boolean isPrimitive(final Class type) {
    if (type.isPrimitive() || isPrimitiveWrapper(type)) {
      return true;
    }
    return false;
  }
  /**
   * Check type against boolean, byte, char, short, int, long, float, double.
   * 
   * @param type
   *          The java type name
   * @return true if this is a primative type name.
   */
  public static boolean isPrimitive(final String type) {
    return PRIMITIVE_NAME_TYPE_MAP.containsKey(type);
  }

  /**
   * Instantiate a java class object
   * 
   * @param expected
   *          the expected class type
   * @param property
   *          the system property defining the class
   * @param defaultClassName
   *          the default class name
   * @return the instantiated object
   */
  public static Object instantiate(Class expected, String property, String defaultClassName) {
    String className = getProperty(property, defaultClassName);
    Class clazz = null;
    try {
      clazz = loadClass(className);
    } catch (ClassNotFoundException e) {
      throw new RuntimeException("Cannot load class " + className, e);
    }
    Object result = null;
    try {
      result = clazz.newInstance();
    } catch (InstantiationException e) {
      throw new RuntimeException("Error instantiating " + className, e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException("Error instantiating " + className, e);
    }
    if (expected.isAssignableFrom(clazz) == false)
      throw new RuntimeException("Class " + className + " from classloader "
          + clazz.getClassLoader() + " is not of the expected class " + expected + " loaded from "
          + expected.getClassLoader());
    return result;
  }
  // ///////////////////////////////////////////////////////////////////////
  // Class Loading //
  // ///////////////////////////////////////////////////////////////////////
  /**
   * This method acts equivalently to invoking
   * <code>Thread.currentThread().getContextClassLoader().loadClass(className);</code>
   * but it also supports primitive types and array classes of object types or
   * primitive types.
   * 
   * @param className
   *          the qualified name of the class or the name of primitive type or
   *          array in the same format as returned by the
   *          <code>java.lang.Class.getName()</code> method.
   * @return the Class object for the requested className
   * 
   * @throws ClassNotFoundException
   *           when the <code>classLoader</code> can not find the requested
   *           class
   */
  public static Class loadClass(String className) throws ClassNotFoundException {
    return loadClass(className, Thread.currentThread().getContextClassLoader());
  }
  /**
   * This method acts equivalently to invoking classLoader.loadClass(className)
   * but it also supports primitive types and array classes of object types or
   * primitive types.
   * 
   * @param className
   *          the qualified name of the class or the name of primitive type or
   *          array in the same format as returned by the
   *          java.lang.Class.getName() method.
   * @param classLoader
   *          the ClassLoader used to load classes
   * @return the Class object for the requested className
   * 
   * @throws ClassNotFoundException
   *           when the <code>classLoader</code> can not find the requested
   *           class
   */
  public static Class loadClass(String className, ClassLoader classLoader)
      throws ClassNotFoundException {
    // ClassLoader.loadClass() does not handle primitive types:
    //
    // B byte
    // C char
    // D double
    // F float
    // I int
    // J long
    // S short
    // Z boolean
    // V void
    //
    if (className.length() == 1) {
      char type = className.charAt(0);
      if (type == "B")
        return Byte.TYPE;
      if (type == "C")
        return Character.TYPE;
      if (type == "D")
        return Double.TYPE;
      if (type == "F")
        return Float.TYPE;
      if (type == "I")
        return Integer.TYPE;
      if (type == "J")
        return Long.TYPE;
      if (type == "S")
        return Short.TYPE;
      if (type == "Z")
        return Boolean.TYPE;
      if (type == "V")
        return Void.TYPE;
      // else throw...
      throw new ClassNotFoundException(className);
    }
    // Check for a primative type
    if (isPrimitive(className) == true)
      return (Class) Classes.PRIMITIVE_NAME_TYPE_MAP.get(className);
    // Check for the internal vm format: Lclassname;
    if (className.charAt(0) == "L" && className.charAt(className.length() - 1) == ";")
      return classLoader.loadClass(className.substring(1, className.length() - 1));
    // first try - be optimistic
    // this will succeed for all non-array classes and array classes that have
    // already been resolved
    //
    try {
      return classLoader.loadClass(className);
    } catch (ClassNotFoundException e) {
      // if it was non-array class then throw it
      if (className.charAt(0) != "[")
        throw e;
    }
    // we are now resolving array class for the first time
    // count opening braces
    int arrayDimension = 0;
    while (className.charAt(arrayDimension) == "[")
      arrayDimension++;
    // resolve component type - use recursion so that we can resolve primitive
    // types also
    Class componentType = loadClass(className.substring(arrayDimension), classLoader);
    // construct array class
    return Array.newInstance(componentType, new int[arrayDimension]).getClass();
  }
  /**
   * Get a system property
   * 
   * @param name
   *          the property name
   * @param defaultValue
   *          the default value
   */
  private static String getProperty(final String name, final String defaultValue) {
    return (String) AccessController.doPrivileged(new PrivilegedAction() {
      public Object run() {
        return System.getProperty(name, defaultValue);
      }
    });
  }
}





Force the given class to be loaded fully.

  
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
public class Main {
  /**
   * Force the given class to be loaded fully.
   * 
   * <p>
   * This method attempts to locate a static method on the given class the
   * attempts to invoke it with dummy arguments in the hope that the virtual
   * machine will prepare the class for the method call and call all of the
   * static class initializers.
   * 
   * @param type
   *          Class to force load.
   * 
   * @throws NullArgumentException
   *           Type is <i>null</i>.
   */
  public static void forceLoad(final Class type) {
    if (type == null)
      System.out.println("Null Argument Exception");
    // don"t attempt to force primitives to load
    if (type.isPrimitive())
      return;
    // don"t attempt to force java.* classes to load
    String packageName = Classes.getPackageName(type);
    // System.out.println("package name: " + packageName);
    if (packageName.startsWith("java.") || packageName.startsWith("javax.")) {
      return;
    }
    // System.out.println("forcing class to load: " + type);
    try {
      Method methods[] = type.getDeclaredMethods();
      Method method = null;
      for (int i = 0; i < methods.length; i++) {
        int modifiers = methods[i].getModifiers();
        if (Modifier.isStatic(modifiers)) {
          method = methods[i];
          break;
        }
      }
      if (method != null) {
        method.invoke(null, (Object[]) null);
      } else {
        type.newInstance();
      }
    } catch (Exception ignore) {
      ignore.printStackTrace();
    }
  }
}





Get a compatible constructor for the given value type

  
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005, JBoss Inc., and individual contributors as indicated
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
public class Main {
  /////////////////////////////////////////////////////////////////////////
  //                           Coercion Methods                          //
  /////////////////////////////////////////////////////////////////////////
  /**
   * Get a compatible constructor for the given value type
   *
   * @param type       Class to look for constructor in
   * @param valueType  Argument type for constructor
   * @return           Constructor or null
   */
  public static Constructor getCompatibleConstructor(final Class type,
                                                     final Class valueType)
  {
     // first try and find a constructor with the exact argument type
     try {
        return type.getConstructor(new Class[] { valueType });
     }
     catch (Exception ignore) {
        // if the above failed, then try and find a constructor with
        // an compatible argument type
        // get an array of compatible types
        Class[] types = type.getClasses();
        for (int i=0; i<types.length; i++) {
           try {
              return type.getConstructor(new Class[] { types[i] });
           }
           catch (Exception ignore2) {}
        }
     }
     // if we get this far, then we can"t find a compatible constructor
     return null;
  }
}





Get the path from where a class is loaded

       
 
public class Main {
  public static void main(String[] args) {
    Main csl = new Main();
    csl.getCodeSourceLocation();
  }
  private void getCodeSourceLocation() {
    System.out.println("Code source location: "
        + getClass().getProtectionDomain().getCodeSource().getLocation());
  }
}





Jar Class Loader

      
/*
 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 * 
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * 
 * - Redistribution in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials
 *   provided with the distribution.
 * 
 * Neither the name of Sun Microsystems, Inc. or the names of
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any
 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
 * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
 * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
 * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR
 * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
 * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
 * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
 * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 * 
 * You acknowledge that this software is not designed, licensed or
 * intended for use in the design, construction, operation or
 * maintenance of any nuclear facility.
 */
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.Attributes;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * A class loader for loading jar files, both local and remote.
 * Adapted from the Java Tutorial.
 *
 * http://java.sun.ru/docs/books/tutorial/jar/api/index.html
 * 
 * @version 1.3 02/27/02
 * @author Mark Davidson
 */
public class JarClassLoader extends URLClassLoader {
    // These manifest attributes were left out of Attributes.Name
    // They have to go somewhere so the chaces are if you need them,
    // then you are playing with this class loader.
    public static final Attributes.Name Attributes_Name_JAVA_BEAN = new Attributes.Name("Java-Bean");
    public static final Attributes.Name Attributes_Name_NAME = new Attributes.Name("Name");
    private static JarClassLoader loader = null;
    
    /** 
     * Null ctor DO NOT USE. This will result in an NPE if the class loader is
     * used. So this class loader isn"t really Bean like.
     */
    public JarClassLoader()  {
        this(null);
    }
    /**
     * Creates a new JarClassLoader for the specified url.
     *
     * @param url The url of the jar file i.e. http://www.xxx.yyy/jarfile.jar
     *            or file:c:\foo\lib\testbeans.jar
     */
    public JarClassLoader(URL url) {
        super(new URL[] { url });
    }
    
    /** 
     * Adds the jar file with the following url into the class loader. This can be 
     * a local or network resource.
     * 
     * @param url The url of the jar file i.e. http://www.xxx.yyy/jarfile.jar
     *            or file:c:\foo\lib\testbeans.jar
     */
    public void addJarFile(URL url)  {
        addURL(url);
    }
    /** 
     * Adds a jar file from the filesystems into the jar loader list.
     * 
     * @param jarfile The full path to the jar file.
     */
    public void addJarFile(String jarfile)  {
        try {
            URL url = new URL("file:" + jarfile);
            addURL(url);
        } catch (IOException ex) {
            Logger.getAnonymousLogger().log(Level.WARNING, "Error adding jar file", ex);
        }
    }
    
    //
    // Static methods for handling the shared instance of the JarClassLoader.
    //
    /** 
     * Returns the shared instance of the class loader.
     */
    public static JarClassLoader getJarClassLoader()  {
        return loader;
    }
    
    /** 
     * Sets the static instance of the class loader.
     */
    public static void setJarClassLoader(JarClassLoader cl)  {
        loader = cl;
    }
}





Java interpreter replacement

  
/*
 * Copyright  2000-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); 
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. 
 *
 */
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
 * Java interpreter replacement, i.e., wrapper that uses its own ClassLoader to
 * modify/generate classes as they"re requested. You can take this as a template
 * for your own applications.<br>
 * Call this wrapper with
 * 
 * 
 * @version $Id: JavaWrapper.java 386056 2006-03-15 11:31:56Z tcurdt $
 * @author 
 * @see ClassLoader
 */
public class JavaWrapper {
  private java.lang.ClassLoader loader;
  private static java.lang.ClassLoader getClassLoader() {
    String s = System.getProperty("bcel.classloader");
    if ((s == null) || "".equals(s)) {
      s = "org.apache.bcel.util.ClassLoader";
    }
    try {
      return (java.lang.ClassLoader) Class.forName(s).newInstance();
    } catch (Exception e) {
      throw new RuntimeException(e.toString());
    }
  }
  public JavaWrapper(java.lang.ClassLoader loader) {
    this.loader = loader;
  }
  public JavaWrapper() {
    this(getClassLoader());
  }
  /**
   * Runs the main method of the given class with the arguments passed in argv
   * 
   * @param class_name
   *          the fully qualified class name
   * @param argv
   *          the arguments just as you would pass them directly
   */
  public void runMain(String class_name, String[] argv) throws ClassNotFoundException {
    Class cl = loader.loadClass(class_name);
    Method method = null;
    try {
      method = cl.getMethod("main", new Class[] { argv.getClass() });
      /*
       * Method main is sane ?
       */
      int m = method.getModifiers();
      Class r = method.getReturnType();
      if (!(Modifier.isPublic(m) && Modifier.isStatic(m)) || Modifier.isAbstract(m)
          || (r != Void.TYPE)) {
        throw new NoSuchMethodException();
      }
    } catch (NoSuchMethodException no) {
      System.out.println("In class " + class_name
          + ": public static void main(String[] argv) is not defined");
      return;
    }
    try {
      method.invoke(null, new Object[] { argv });
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  /**
   * Default main method used as wrapper, expects the fully qualified class name
   * of the real class as the first argument.
   */
  public static void main(String[] argv) throws Exception {
    /*
     * Expects class name as first argument, other arguments are by-passed.
     */
    if (argv.length == 0) {
      System.out.println("Missing class name.");
      return;
    }
    String class_name = argv[0];
    String[] new_argv = new String[argv.length - 1];
    System.arraycopy(argv, 1, new_argv, 0, new_argv.length);
    JavaWrapper wrapper = new JavaWrapper();
    wrapper.runMain(class_name, new_argv);
  }
}





Load Class

    
// $Id: ReflectionHelper.java 16271 2009-04-07 20:20:12Z hardy.ferentschik $
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,  
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Some reflection utility methods.
 *
 * @author Hardy Ferentschik
 */
public class ReflectionHelper {
  public static Class<?> loadClass(String name, Class<?> caller) throws ClassNotFoundException {
    try {
      //try context classloader, if fails try caller classloader
      ClassLoader loader = Thread.currentThread().getContextClassLoader();
      if ( loader != null ) {
        return loader.loadClass( name );
      }
    }
    catch ( ClassNotFoundException e ) {
      //trying caller classloader
      if ( caller == null ) {
        throw e;
      }
    }
    return Class.forName( name, true, caller.getClassLoader() );
  }
}





Load classes

    
/**
 * EasyBeans
 * Copyright (C) 2006 Bull S.A.S.
 * Contact: easybeans@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id: ClassUtils.java 3783 2008-07-30 13:44:06Z benoitf $
 * --------------------------------------------------------------------------
 */

/**
 * The <code>ClassUtils</code> class is the central point used to load classes.
 * @author Guillaume Sauthier
 */
public final class ClassUtils {
    /**
     * Default constructor.
     */
    private ClassUtils() {}
    /**
     * Look up the class in the Tread Context ClassLoader and in the "current" ClassLoader.
     * @param className The class name to load
     * @return the corresponding Class instance
     * @throws ClassNotFoundException if the Class was not found.
     */
    public static Class forName(final String className) throws ClassNotFoundException {
        // Load classes from different classloaders :
        // 1. Thread Context ClassLoader
        // 2. ClassUtils ClassLoader
        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
        Class cls = null;
        try {
            // Try with TCCL
            cls = Class.forName(className, true, tccl);
        } catch (ClassNotFoundException cnfe) {
            // Try now with the classloader used to load ClassUtils
            ClassLoader current = ClassUtils.class.getClassLoader();
            try {
                cls = Class.forName(className, true, current);
            } catch (ClassNotFoundException cnfe2) {
                // If this is still unknown, throw an Exception
                throw cnfe2;
            }
        }
        return cls;
    }
    /**
     * Look up the class in the Tread Context ClassLoader and in the "current" ClassLoader.
     * @param className The class name to load
     * @param clazz a class used to get classloader
     * @return the corresponding Class instance
     * @throws ClassNotFoundException if the Class was not found.
     */
    public static Class forName(final String className, final Class clazz) throws ClassNotFoundException {
        // Load classes from different classloaders :
        // 1. Thread Context ClassLoader
        // 2. ClassUtils ClassLoader
        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
        Class cls = null;
        try {
            // Try with TCCL
            cls = Class.forName(className, true, tccl);
        } catch (ClassNotFoundException cnfe) {
            // Try now with the classloader used to load ClassUtils
            ClassLoader current = clazz.getClassLoader();
            if (current != null) {
                try {
                    cls = Class.forName(className, true, current);
                } catch (ClassNotFoundException cnfe2) {
                    // If this is still unknown, throw an Exception
                    throw new ClassNotFoundException("Class Not found in current ThreadClassLoader "" + tccl + "" and in "" + current + "" classloaders.", cnfe2);
                }
            } else {
                // rethrow exception
                throw cnfe;
            }
        }
        return cls;
    }

}





Load class from Thread"s ContextClassLoader, classloader of derived class or the system ClassLoader

     
// 
// Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at 
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 

import java.net.URL;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/* ------------------------------------------------------------ */
/** ClassLoader Helper.
 * This helper class allows classes to be loaded either from the
 * Thread"s ContextClassLoader, the classloader of the derived class
 * or the system ClassLoader.
 *
 * <B>Usage:</B><PRE>
 * public class MyClass {
 *     void myMethod() {
 *          ...
 *          Class c=Loader.loadClass(this.getClass(),classname);
 *          ...
 *     }
 * </PRE>          
 * @author Greg Wilkins (gregw)
 */
public class Loader
{
    /* ------------------------------------------------------------ */
    public static URL getResource(Class loadClass,String name, boolean checkParents)
        throws ClassNotFoundException
    {
        URL url =null;
        ClassLoader loader=Thread.currentThread().getContextClassLoader();
        while (url==null && loader!=null )
        {
            url=loader.getResource(name); 
            loader=(url==null&&checkParents)?loader.getParent():null;
        }      
        
        loader=loadClass==null?null:loadClass.getClassLoader();
        while (url==null && loader!=null )
        {
            url=loader.getResource(name); 
            loader=(url==null&&checkParents)?loader.getParent():null;
        }       
        if (url==null)
        {
            url=ClassLoader.getSystemResource(name);
        }   
        return url;
    }
    /* ------------------------------------------------------------ */
    public static Class loadClass(Class loadClass,String name)
        throws ClassNotFoundException
    {
        return loadClass(loadClass,name,false);
    }
    
    /* ------------------------------------------------------------ */
    /** Load a class.
     * 
     * @param loadClass
     * @param name
     * @param checkParents If true, try loading directly from parent classloaders.
     * @return Class
     * @throws ClassNotFoundException
     */
    public static Class loadClass(Class loadClass,String name,boolean checkParents)
        throws ClassNotFoundException
    {
        ClassNotFoundException ex=null;
        Class c =null;
        ClassLoader loader=Thread.currentThread().getContextClassLoader();
        while (c==null && loader!=null )
        {
            try { c=loader.loadClass(name); }
            catch (ClassNotFoundException e) {if(ex==null)ex=e;}
            loader=(c==null&&checkParents)?loader.getParent():null;
        }      
        
        loader=loadClass==null?null:loadClass.getClassLoader();
        while (c==null && loader!=null )
        {
            try { c=loader.loadClass(name); }
            catch (ClassNotFoundException e) {if(ex==null)ex=e;}
            loader=(c==null&&checkParents)?loader.getParent():null;
        }       
        if (c==null)
        {
            try { c=Class.forName(name); }
            catch (ClassNotFoundException e) {if(ex==null)ex=e;}
        }   
        if (c!=null)
            return c;
        throw ex;
    }
    public static ResourceBundle getResourceBundle(Class loadClass,String name,boolean checkParents, Locale locale)
        throws MissingResourceException
    {
        MissingResourceException ex=null;
        ResourceBundle bundle =null;
        ClassLoader loader=Thread.currentThread().getContextClassLoader();
        while (bundle==null && loader!=null )
        {
            try { bundle=ResourceBundle.getBundle(name, locale, loader); }
            catch (MissingResourceException e) {if(ex==null)ex=e;}
            loader=(bundle==null&&checkParents)?loader.getParent():null;
        }      
        
        loader=loadClass==null?null:loadClass.getClassLoader();
        while (bundle==null && loader!=null )
        {
            try { bundle=ResourceBundle.getBundle(name, locale, loader); }
            catch (MissingResourceException e) {if(ex==null)ex=e;}
            loader=(bundle==null&&checkParents)?loader.getParent():null;
        }       
        if (bundle==null)
        {
            try { bundle=ResourceBundle.getBundle(name, locale); }
            catch (MissingResourceException e) {if(ex==null)ex=e;}
        }   
        if (bundle!=null)
            return bundle;
        throw ex;
    }
    
}





Loading a Class That Is Not on the Classpath

       
A URLClassLoader can be used to load classes in any directory.
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
public class Main {
  public static void main(String[] argv) throws Exception {
    File file = new File("c:\\");
    URL url = file.toURI().toURL(); 
    URL[] urls = new URL[] { url };
    ClassLoader cl = new URLClassLoader(urls);
    Class cls = cl.loadClass("com.mycompany.MyClass");
  }
}





Return the context classloader.

      
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.net.MalformedURLException;
import java.net.URL;
/**
 * A collection of class management utility methods.
 *
 * @version $Id: ClassUtils.java 587751 2007-10-24 02:41:36Z vgritsenko $
 */
public class ClassUtils {

    /**
     * Return the context classloader.
     * BL: if this is command line operation, the classloading issues
     *     are more sane.  During servlet execution, we explicitly set
     *     the ClassLoader.
     *
     * @return The context classloader.
     */
    public static ClassLoader getClassLoader() {
        return Thread.currentThread().getContextClassLoader();
    }
}





Unqualified names

       
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Main {
  public static void main(String[] argv) throws Exception {
    Class cls = java.lang.String.class;
    Method method = cls.getMethods()[0];
    Field field = cls.getFields()[0];
    Constructor constructor = cls.getConstructors()[0];
    String name;
    name = cls.getName().substring(cls.getPackage().getName().length()+1);  
    System.out.println(name);
    name = field.getName();  
    System.out.println(name);
    name = constructor.getName().substring(cls.getPackage().getName().length()+1);
    System.out.println(name);
    name = method.getName(); 
    System.out.println(name);
  }
}
/*String
CASE_INSENSITIVE_ORDER
String
hashCode
*/





Using the forName() method

       
public class Main {
  public static void main(String[] argv) throws Exception {
    Class cc = null;
    cc = Class.forName("Main.class");
  }
}





Utility to essentially do Class forName and allow configurable Classloaders.

 
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
/*
 * Copyright 2005 Joe Walker
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @author Joe Walker [joe at getahead dot ltd dot uk]
 */
public class Main {
  /**
   * Utility to essentially do Class forName and allow configurable
   * Classloaders.
   * <p>The initial implementation makes use of the context classloader for
   * the current thread.
   * @param className The class to create
   * @return The class if it is safe or null otherwise.
   * @throws ClassNotFoundException If <code>className</code> is not valid
   */
  public static Class<?> classForName(String className) throws ClassNotFoundException
  {
      // Class.forName(className);
      return Thread.currentThread().getContextClassLoader().loadClass(className);
  }
}





Various Class Loader utilities

    
/***
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *    Project: www.simpledbm.org
 *    Author : Dibyendu Majumdar
 *    Email  : dibyendu@mazumdar.demon.co.uk
 */
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * Various Class Loader utilities. 
 * @author Dibyendu Majumdar
 * @since 14.Jan.2005
 */
public final class ClassUtils {
  private static final String LOG_CLASS_NAME = ClassUtils.class.getName();
  /**
   * Get the ClassLoader to use. We always use the current Thread"s
   * Context ClassLoader. Assumption is that all threads within the
   * application share the same ClassLoader.
   */
  private static ClassLoader getClassLoader() {
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      if (cl == null) {
          throw new NullPointerException();
      }
      return cl;
  }
  
  
  /**
   * A wrapper for Class.forName() so that we can change the behaviour
   * globally without changing the rest of the code.
   * 
   * @param name Name of the class to be loaded
   * @throws ClassNotFoundException
   */
  public static Class forName(String name) throws ClassNotFoundException {
    ClassLoader cl = getClassLoader();
    Class clazz = null;
    clazz = Class.forName(name, true, cl);
    return clazz;
  }
  /**
   * Load a properties file from the classpath.
   * 
   * @param name Name of the properties file
   * @throws IOException If the properties file could not be loaded
   */
  public static InputStream getResourceAsStream(String name) throws IOException {
      ClassLoader cl = getClassLoader();
      InputStream is = null;
        is = cl.getResourceAsStream(name);
      if (is == null) {
          throw new IOException("Unable to load "+ " " + name);
      }
      return is;
  }
  
  
  /**
   * Load a properties file from the classpath.
   * 
   * @param name Name of the properties file
   * @throws IOException If the properties file could not be loaded
   */
  public static Properties getResourceAsProperties(String name) throws IOException {
      ClassLoader cl = getClassLoader();
      InputStream is = null;
        is = cl.getResourceAsStream(name);
      if (is == null) {
          throw new IOException("Unable to load "+ " " + name);
      }
      Properties props = new Properties();
      props.load(is);
      return props;
  }
  /**
   * Helper for invoking an instance method that takes a single parameter.
   * This method also handles parameters of primitive type.
   * 
   * @param cl
   *            The class that the instance belongs to
   * @param instance
   *            The object on which we will invoke the method
   * @param methodName
   *            The method name
   * @param param
   *            The parameter
   * @throws Throwable
   */
  public static Object invokeMethod(Class cl, Object instance,
      String methodName, Object param) throws Throwable {
      Class paramClass;
      if (param instanceof Integer)
          paramClass = Integer.TYPE;
      else if (param instanceof Long) 
          paramClass = Long.TYPE;
      else if (param instanceof Short)
          paramClass = Short.TYPE;
      else if (param instanceof Boolean)
          paramClass = Boolean.TYPE;
      else if (param instanceof Double)
          paramClass = Double.TYPE;
      else if (param instanceof Float)
          paramClass = Float.TYPE;
      else if (param instanceof Character)
          paramClass = Character.TYPE;
      else if (param instanceof Byte)
          paramClass = Byte.TYPE;
      else
          paramClass = param.getClass();
    Method method = cl.getMethod(methodName,
        new Class[] { paramClass });
    try {
      return method.invoke(instance, new Object[] { param });
    } catch (InvocationTargetException e) {
      throw e.getCause();
    }
  }
  
  /**
   * Helper for invoking a static method that takes one parameter.
   * 
   * @param cl
   *            The class that implements the static method
   * @param methodName
   *            The method name
   * @param param
   *            A parameter
   * @param paramClass
   *            Class of the parameter
   * @throws Throwable
   */
  public static Object invokeStaticMethod(Class cl, String methodName,
      Object param, Class paramClass) throws Throwable {
    Method method = cl.getMethod(methodName, new Class[] { paramClass });
    try {
      return method.invoke(null, new Object[] { param });
    } catch (InvocationTargetException e) {
      throw e.getCause();
    }
  }
  /**
   * Helper for invoking a constructor with one parameter.
   * 
   * @param className Class of which an instance is to be allocated
   * @param param Parameter
   * @param paramClass Type of the parameter
   * @throws ClassNotFoundException
   * @throws SecurityException
   * @throws NoSuchMethodException
   * @throws IllegalArgumentException
   * @throws InstantiationException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   */
  public static Object createObject(String className, Object param, Class paramClass)
      throws ClassNotFoundException, SecurityException,
      NoSuchMethodException, IllegalArgumentException,
      InstantiationException, IllegalAccessException,
      InvocationTargetException {
    Class clazzImpl = ClassUtils.forName(className);
    Constructor ctor = clazzImpl
        .getConstructor(new Class[] { paramClass });
    Object instance = ctor.newInstance(new Object[] { param });
    return instance;
  }
}





Zip Class Loader

     
/* Copyright (c) 2006, 2009, Carl Burch. License information is located in the
 * com.cburch.logisim.Main source code and at www.cburch.ru/logisim/. */
 
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class ZipClassLoader extends ClassLoader {
    // This code was posted on a forum by "leukbr" on March 30, 2001.
    // http://forums.sun.ru/thread.jspa?threadID=360060&forumID=31
    // I"ve modified it substantially to include a thread that keeps the file
    // open for OPEN_TIME milliseconds so time isn"t wasted continually
    // opening and closing the file.
    private static final int OPEN_TIME = 5000;
    private static final int DEBUG = 0;
        // 0 = no debug messages
        // 1 = open/close ZIP file only
        // 2 = also each resource request
        // 3 = all messages while retrieving resource
    
    private static final int REQUEST_FIND = 0;
    private static final int REQUEST_LOAD = 1;
    
    private static class Request {
        int action;
        String resource;
        boolean responseSent;
        Object response;
        
        Request(int action, String resource) {
            this.action = action;
            this.resource = resource;
            this.responseSent = false;
        }
        
        public String toString() {
            String act = action == REQUEST_LOAD ? "load"
                    : action == REQUEST_FIND ? "find" : "act" + action;
            return act + ":" + resource;
        }
        
        void setResponse(Object value) {
            synchronized(this) {
                response = value;
                responseSent = true;
                notifyAll();
            }
        }
        
        void ensureDone() {
            boolean aborted = false;
            synchronized(this) {
                if(!responseSent) {
                    aborted = true;
                    responseSent = true;
                    response = null;
                    notifyAll();
                }
            }
            if(aborted && DEBUG >= 1) {
                System.err.println("request not handled successfully"); //OK
            }
        }
        
        Object getResponse() {
            synchronized(this) {
                while(!responseSent) {
                    try { this.wait(1000); } catch(InterruptedException e) { }
                }
                return response;
            }
        }
    }
    
    private class WorkThread extends Thread {
        private LinkedList requests = new LinkedList();
        private ZipFile zipFile = null;
        
        public void run() {
            try {
                while(true) {
                    Request request = waitForNextRequest();
                    if(request == null) return;
                    
                    if(DEBUG >= 2) System.err.println("processing " + request); //OK
                    try {
                        switch(request.action) {
                        case REQUEST_LOAD: performLoad(request); break;
                        case REQUEST_FIND: performFind(request); break;
                        }
                    } finally {
                        request.ensureDone();
                    }
                    if(DEBUG >= 2) System.err.println("processed: " + request.getResponse()); //OK
                }
            } catch(Throwable t) {
                if(DEBUG >= 3) { System.err.print("uncaught: "); t.printStackTrace(); } //OK
            } finally {
                if(zipFile != null) {
                    try {
                        zipFile.close();
                        zipFile = null;
                        if(DEBUG >= 1) System.err.println("  ZIP closed"); //OK
                    } catch(IOException e) {
                        if(DEBUG >= 1) System.err.println("Error closing ZIP file"); //OK
                    }
                }
            }
        }
        
        private Request waitForNextRequest() {
            synchronized(bgLock) {
                long start = System.currentTimeMillis();
                while(requests.isEmpty()) {
                    long elapse = System.currentTimeMillis() - start;
                    if(elapse >= OPEN_TIME) {
                        bgThread = null;
                        return null;
                    }
                    try {
                        bgLock.wait(OPEN_TIME);
                    } catch(InterruptedException e) { }
                }
                return (Request) requests.removeFirst();
            }
        }
        
        private void performFind(Request req) {
            ensureZipOpen();
            Object ret = null;
            try {
                if(zipFile != null) {
                    if(DEBUG >= 3) System.err.println("  retrieve ZIP entry"); //OK
                    String res = req.resource;
                    ZipEntry zipEntry = zipFile.getEntry(res);
                    if(zipEntry != null) {
                        String url = "jar:" + zipPath.toURI() + "!/" + res;
                        ret = new URL(url);
                        if(DEBUG >= 3) System.err.println("  found: " + url); //OK
                    }
                }
            } catch(Throwable ex) {
                if(DEBUG >= 3) System.err.println("  error retrieving data"); //OK
                ex.printStackTrace();
            }
            req.setResponse(ret);
        }
        
        private void performLoad(Request req) {
            BufferedInputStream bis = null;
            ensureZipOpen();
            Object ret = null;
            try {
                if(zipFile != null) {
                    if(DEBUG >= 3) System.err.println("  retrieve ZIP entry"); //OK
                    ZipEntry zipEntry = zipFile.getEntry(req.resource);
                    if(zipEntry != null) {
                        if(DEBUG >= 3) System.err.println("  load file"); //OK
                        byte[] result = new byte[(int) zipEntry.getSize()];
                        bis = new BufferedInputStream(zipFile.getInputStream(zipEntry));
                        try {
                            bis.read(result, 0, result.length);
                            ret = result;
                        } catch(IOException e) {
                            if(DEBUG >= 3) System.err.println("  error loading file"); //OK
                        }
                    }
                }
            } catch(Throwable ex) {
                if(DEBUG >= 3) System.err.println("  error retrieving data"); //OK
                ex.printStackTrace();
            } finally {
                if (bis!=null) {
                    try {
                        if(DEBUG >= 3) System.err.println("  close file"); //OK
                        bis.close();
                    } catch (IOException ioex) {
                        if(DEBUG >= 3) System.err.println("  error closing data"); //OK
                    }
                }
            }
            req.setResponse(ret);
        }
        
        private void ensureZipOpen() {
            if(zipFile == null) {
                try {
                    if(DEBUG >= 3) System.err.println("  open ZIP file"); //OK
                    zipFile = new ZipFile(zipPath);
                    if(DEBUG >= 1) System.err.println("  ZIP opened");  //OK
                } catch(IOException e) {
                    if(DEBUG >= 1) System.err.println("  error opening ZIP file"); //OK
                }
            }
        }
    }
    
    private File zipPath;
    private HashMap classes = new HashMap();
    private Object bgLock = new Object();
    private WorkThread bgThread = null;
 
    public ZipClassLoader(String zipFileName) {
        this(new File(zipFileName));
    }
 
    public ZipClassLoader(File zipFile) {
        zipPath = zipFile;
    }
    
    public URL findResource(String resourceName) {
        if(DEBUG >= 3) System.err.println("findResource " + resourceName); //OK
        Object ret = request(REQUEST_FIND, resourceName);
        if(ret instanceof URL) {
            return (URL) ret;
        } else {
            return super.findResource(resourceName);
        }
    }
    public Class findClass(String className) throws ClassNotFoundException {
        boolean found = false;
        Object result = null;
        // check whether we have loaded this class before
        synchronized(classes) {
            found = classes.containsKey(className);
            if(found) result = classes.get(className);
        }
        // try loading it from the ZIP file if we haven"t
        if(!found) {
            String resourceName = className.replace(".", "/") + ".class";
            result = request(REQUEST_LOAD, resourceName);
            if(result instanceof byte[]) {
                if(DEBUG >= 3) System.err.println("  define class"); //OK
                byte[] data = (byte[]) result;
                result = defineClass(className, data, 0, data.length);
                if(result != null) {
                    if(DEBUG >= 3) System.err.println("  class defined"); //OK
                } else {
                    if(DEBUG >= 3) System.err.println("  format error"); //OK
                    result = new ClassFormatError(className);
                }
            }
            synchronized(classes) { classes.put(className, result); }
        }
        
        if(result instanceof Class) {
            return (Class) result;
        } else if(result instanceof ClassNotFoundException) {
            throw (ClassNotFoundException) result;
        } else if(result instanceof Error) {
            throw (Error) result;
        } else {
            return super.findClass(className);
        }
    }
    
    private Object request(int action, String resourceName) {
        Request request;
        synchronized(bgLock) {
            if(bgThread == null) { // start the thread if it isn"t working
                bgThread = new WorkThread();
                bgThread.start();
            }
            request = new Request(action, resourceName);
            bgThread.requests.addLast(request);
            bgLock.notifyAll();
        }
        return request.getResponse();
    }
}