URLClassLoader是ClassLoader的子类,它用于从指向 JAR 文件和目录的 URL 的搜索路径加载类和资源。也就是说,通过URLClassLoader就可以加载指定jar中的class到内存中。
Java代码
- package hb.classloader;
- import java.io.File;
- import java.lang.reflect.Method;
- import java.net.URL;
- import java.net.URLClassLoader;
- public class URLClassLoaderDemo1 {
- public static void main(String[] args) throws Exception
- {
- try
- {
- Class.forName("org.apache.commons.lang.StringUtils");
- }
- catch(Exception e)
- {
- System.out.println("exception happen!");
- e.printStackTrace();
- }
- File file = new File("c:"+File.separator+"commons-lang-1.0-b1.jar");
- URL url = file.toURI().toURL();
- URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url});
- Class clazz = urlClassLoader.loadClass("org.apache.commons.lang.StringUtils");
- Method isEmpty = clazz.getMethod("isEmpty", String.class);
- System.out.println(isEmpty.invoke(null,"This is not empty!"));
- System.out.println(isEmpty.invoke(null,""));
- }
- }
打印结果:
exception hapen
java.lang.ClassNotFoundException: org.apache.commons.lang.StringUtils
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at hb.classloader.URLClassLoaderDemo1.main(URLClassLoaderDemo1.java:14)
false
true
备注:由于加载org.apache.commons.lang.StringUtils类,在JVM中查找不到,也就是说没有引用相关的jar包,因此会抛出异常。通过URLClassLoader加载相关的jar(里面包含指定的java类),则不会再抛出异常,通过反射获取该类的方法。
如果希望上面的代码不抛出异常,可以有两种方法解决:
1、引用commons-lang-1.0-b1.jar
2、在%JRE_HOME%/lib/ext下面添加commons-lang-1.0-b1.jar。
这是因为在App ClassLoader找不到该引用的Class对象就会去找其parent (Extension ClassLoader) ,它就是引用%JRE_HOME%/lib/ext目录下面的所有jar包,如果这里面没有就会继续找其parent(Bootstrap ClassLoader),它的引用在 %JRE_HOME/lib/ 目录下的所有jar,如果这个没有就会报错了