要写插件系统,避免不了要使用ClassLoader,一般都使用现有的URLClassLoader.之前用过URLClassLoader,忘记了不少用法
,所以今天再test test.
- Java code
public class URLClassLoaderextends SecureClassLoader该类加载器用于从指向 JAR 文件和目录的 URL 的搜索路径加载类和资源。这里假定任何以 '/' 结束的 URL 都是指向目录的。如果不是以该字符结束,则认为该 URL 指向一个将根据需要打开的 JAR 文件。
以上是中文版的URLClassLoader的doc,我从上面这段话里得到一个信息:可以向URLClassLoader指定目录的URL,并且URLClassLoader是会搜索目录下的文件的.
但事实却并非如此.
1.先看目录结构
2.代码
- Java code
public class Main { /** * @param args * @throws MalformedURLException * @throws ClassNotFoundException */ public static void main(String[] args) throws MalformedURLException, ClassNotFoundException { File f = new File("lib"); MyClassLoader loader = new MyClassLoader(); File[] files = f.listFiles(); for(File file: files){ if(file.exists()){ //loader.addFile(file); // A.添加lib下的所有文件到URLClassLoader System.out.println(file.getAbsolutePath()); } } loader.addFile(f); // B.添加 lib目录到URLCLassLoader System.out.println(loader.getParent()); String className = "org.apache.commons.lang.StringUtils"; loader.loadClass(className); } static class MyClassLoader extends URLClassLoader{ public MyClassLoader(URL[] urls) { super(urls); } public MyClassLoader(){ super(new URL[]{}); } public void addFile(File f) throws MalformedURLException{ this.addURL(f.toURI().toURL()); System.out.println("URL:" + f.toURI().toURL()); } }}
看第一个注释处
若注释掉"loader.addFile(file)",则java.lang.ClassNotFoundException
反之,程序正常运行
第二个注释处,有无"loader.addFile(f);"对结果并无影响
结论:向URLClassLoader添加目录是无效的,URLClassLoader并不会搜索或者将目录下的所有文件添加进classpath
另外,URLClassLoader的doc写得是不是有歧义?
欢迎斧正,拍砖.
------解决方案--------------------
LZ可能没完全理解文档说明
jar文件相当于一个文件夹
所以如果是加载文件夹,应该是相应的class文件在该文件夹内,而不是jar文件在该文件夹内
也就是说,加载文件夹,不会搜索该文件夹的jar,只会搜索该文件夹下的class文件
就好像classpath环境变量不能设置 xxxpath/*.jar一样,必须一个一个jar追加,所以只是设置xxxpath/,就只会搜索xxxpath下的class文件
------解决方案--------------------
这样一个目录结构是可以正常加载到org.apache.commons.beanutils.里面的类的
但是明显是不可能加载org.apache.commons.lang.StringUtils这个类,因为在lib目录中不存在
org\apache\commons\lang\StringUtils.class文件!
URLClassLoader不会试图从commons-lang-2.6.jar中加载的,因为你只向URLClassLoader中加入了lib目录,而不是commons-lang-2.6.jar