如何在运行时添加classpath

来源:互联网 发布:淘宝机器人在哪 编辑:程序博客网 时间:2024/05/01 19:06

这几天在做一个小项目的时候 有这样一个需求, 程序需要动态引入一个.class文件,然后用Class.forName(name)将其载入,从而得到.class文件的信息.如果是在系统当前指定的classpath下,可以直接载入,但是若是自定义的路径下的.class文件,就会报找不到类文件的错.后来我问了老师,老师提供的方法是用ClassLoader.defineClass(byte[] b, int off, int len)来载入.class文件,这种方法已经成功.但我在想,怎么能将这个文件的路径加入classpath中呢,开始我想到了System.setProperty(String key, String value)这个方法,但后来证明是错的,这种方式是对classpath不起作用的,因为系统的类加载器在启动期间很早的时候就读取classpath了,系统在后来是不再读取classpath的,所以修改对系统没有任何作用.这几天在google看到一篇文章,这位国外的仁兄用了一种方法,可以实现动态添加自定义classpath,很好的程序,转载来学习一下.  

package com.dawn.scm.util;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;


/**
 * Allows programs to modify the classpath during runtime.
 * 
 * @author Yucheng
 *
 */
public class ClassPathUpdater {


        /** Used to find the method signature. */
        @SuppressWarnings("rawtypes")
        private static final Class[] PARAMETERS = new Class[] { URL.class };
        
        /** Class containing the private addURL method. */
        @SuppressWarnings("rawtypes")
        private static final Class CLASS_LOADER = URLClassLoader.class;
        
        /** 
           * Adds a new path to the classloader. If the given string points to a file, 
           * then that file's parent file (i.e., directory) is used as the 
           * directory to add to the classpath. If the given string represents a 
           * directory, then the directory is directly added to the classpath. 
           * 
           * @param s The directory to add to the classpath (or a file, which 
           * will relegate to its directory). 
           */  
          public static void add( String s )  
            throws IOException, NoSuchMethodException, IllegalAccessException,  
                   InvocationTargetException {  
            add( new File( s ) );  
          }  
          
          /** 
           * Adds a new path to the classloader. If the given file object is 
           * a file, then its parent file (i.e., directory) is used as the directory 
           * to add to the classpath. If the given string represents a directory, 
           * then the directory it represents is added. 
           * 
           * @param f The directory (or enclosing directory if a file) to add to the 
           * classpath. 
           */  
          private static void add( File f )  
            throws IOException, NoSuchMethodException, IllegalAccessException,  
                   InvocationTargetException {
            f = f.isDirectory() ? f : f.getParentFile();  
            add( f.toURI().toURL() );  
          }  
          
          /** 
           * Adds a new path to the classloader. The class must point to a directory, 
           * not a file. 
           * 
           * @param url The path to include when searching the classpath. 
           */  
          @SuppressWarnings("unchecked")
        private static void add( URL url )  
            throws IOException, NoSuchMethodException, IllegalAccessException,  
                   InvocationTargetException {  
                Method method = CLASS_LOADER.getDeclaredMethod( "addURL", PARAMETERS );  
            method.setAccessible( true );  
            method.invoke( getClassLoader(), new Object[]{ url } );  
          }  
          
          private static URLClassLoader getClassLoader() {  
            return (URLClassLoader)Thread.currentThread().getContextClassLoader();  
          }  

}

出处:

http://code.google.com/p/dawnwork/source/browse/trunk/dawn_saas_scm/src/com/dawn/scm/util/ClassPathUpdater.java?spec=svn195&r=195

http://ted0928.iteye.com/blog/543599

原创粉丝点击