content: package com.alimama.quanjingmonitor.tt;
  
  import java.io.*;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipException;
  import java.util.zip.ZipFile;
  
  /**
   * 从指定目录、jar文件加载类</p>
   * 
   * 使用：通过下面的方式扩展当前加载器
   *		ClassLoader cld=new DynaClassLoader(Thread.currentThread().getContextClassLoader());
   *		cld.addEtries(****);
   *		Thread.currentThread().setContextClassLoader();
   */
  public class DynaClassLoader extends ClassLoader {
  
      //类资源,目录或者是jar
      private List<File> entries = new ArrayList<File>();
  
      /**
       * @param parent
       * @param entries
       */
      public DynaClassLoader(ClassLoader parent, File[] entries) {
          super(parent);
          this.entries.addAll(Arrays.asList(entries));
      }
  
      /**
       * @param parent
       */
      public DynaClassLoader(ClassLoader parent) {
          super(parent);
      }
  
      /**
       * @param fs
       */
      public void addEtries(File[] fs) {
          this.entries.addAll(Arrays.asList(fs));
      }
  
      public void clear() {
          this.entries.clear();
      }
  
      /**
       * @param fs
       */
      public void addEtry(File fs) {
          this.entries.add(fs);
      }
  
      public String toString() {
          String buf = "";
          for (File file : entries) {
              buf += file.getAbsolutePath() + ";";
          }
          return buf;
      }
  
      /**
       * 加载class
       * <p/>
       * todo 是否需做缓存、仔细仿照父loadClass的过程、使用参数b
       */
      protected Class loadClass(String name, boolean b)
              throws ClassNotFoundException {
  
          //优先从父加载器获取
          Class clazz = null;
          try {
              clazz = super.loadClass(name, b);
              if (clazz != null) {
                  return clazz;
              }
          } catch (ClassNotFoundException e) {
          }
  
          //System.out.println("DynaClassLoader:load class->" + name);
  
          int dotIndex = name.indexOf(".");
  
          String separator = File.separator;
          if (separator.equals("\\")) {
              separator = "\\\\";
          }
  
          String fileName;
          if (dotIndex != -1) {
              fileName = new StringBuilder().append(name.replaceAll("\\.", separator)).append(".class").toString();
          } else {
              fileName = new StringBuilder().append(name).append(".class").toString();
          }
  
          InputStream is = getLocalResourceAsStream(fileName);
          if (is == null) {
              throw new ClassNotFoundException(name);
          }
  
          try {
              Class loadedClass = readClass(name, is);
              is.close();
              if (loadedClass != null) {
                  return loadedClass;
              } else {
                  throw new ClassNotFoundException(name);
              }
          } catch (Exception e) {
              throw new ClassNotFoundException(name);
          } finally {
              try {
                  is.close();
              } catch (IOException e) {
              }
          }
  
      }
  
      private Class readClass(String className, InputStream is) throws IOException {
          BufferedInputStream bis = new BufferedInputStream(is);
          ByteArrayOutputStream os = new ByteArrayOutputStream();
          byte[] bytes = new byte[1024 * 10];
          int readBytes;
          while ((readBytes = bis.read(bytes)) != -1) {
              os.write(bytes, 0, readBytes);
          }
          byte[] b = os.toByteArray();
          return defineClass(className, b, 0, b.length);
      }
  
      /**
       *
       * @param name
       * @return
       */
      private URL getLocalResource(String name) {
  
          for (int i = 0; i < entries.size(); i++) {
              File entry = entries.get(i);
              if (entry.isDirectory() && entry.exists()) {
                  File f = new File(entry, name);
                  if (f.exists()) {
                      URL url;
                      try {
                          url = f.toURI().toURL();
  
                      } catch (MalformedURLException ex) {
                          continue;
                      }
                      return url;
                  }
              } else if (entry.isFile() && entry.exists()) {
                  URL url = null;
                  try {
                      ZipFile zf = new ZipFile(entry);
                      name = name.replaceAll("\\\\", "/");
                      ZipEntry zipEntry = zf.getEntry(name);
                      if (zipEntry == null) {
                          continue;
                      }
                      String url_0_ = entry.getAbsolutePath().replaceAll("\\\\", "/");
                      if (!url_0_.startsWith("/")) {
                          url_0_ = new StringBuilder().append("/").append(url_0_).toString();
                      }
                      url = new URL(new StringBuilder().append("jar:file://").append(url_0_).append("!/").append(name).toString());
                  } catch (ZipException zipexception) {
                      zipexception.printStackTrace();
                  } catch (IOException ioexception) {
                      ioexception.printStackTrace();
                  }
                  return url;
              }
          }
          return null;
      }
  
      private InputStream getLocalResourceAsStream(String name) {
          URL res = getLocalResource(name);
          if (res == null) {
              return null;
          }
          InputStream inputstream = null;
          try {
              inputstream = res.openStream();
          } catch (IOException ex) {
              ex.printStackTrace();
  
          }
          return inputstream;
      }
  
      /**
       * 加载数据流
       */
      public InputStream getResourceAsStream(String name) {
          InputStream _super = super.getResourceAsStream(name);
          return _super != null ? _super : getLocalResourceAsStream(name);
      }
  
      /**
       * 加载资源
       */
      public URL getResource(String name) {
          URL resource = super.getResource(name);
          return resource != null ? resource : getLocalResource(name);
      }
  }
  