`

URLClassLoader类

    博客分类:
  • java
 
阅读更多

引自http://wenku.baidu.com/view/7d6e427002768e9951e73863.html
我们知道,Java利用ClassLoader将类载入内存,并且在同一应用中,可以有很多个ClassLoader,通过委派机制,把装载的任务传递给上级的装载器的,依次类推,直到启动类装载器(没有上级类装载器)。如果启动类装载器能够装载这个类,那么它会首先装载。如果不能,则往下传递。当父类为null时,JVM内置的类(称为:bootstrap class loader)就会充当父类。想想眼下的越来越多用XML文件做配置文件或者是描述符、部署符。其实这些通过XML文档描述的配置信息最终都要变成 Java类,基实都是通过ClassLoader来完成的。URLClassLoader是ClassLoader的子类,它用于从指向 JAR 文件和目录的 URL 的搜索路径加载类和资源。也就是说,通过URLClassLoader就可以加载指定jar中的class到内存中。

下面来看一个例子,在该例子中,我们要完成的工作是利用URLClassLoader加载jar并运行其中的类的某个方法。

首先我们定义一个接口,使所有继承它的类都必须实现action方法,如下:

public interface ActionInterface {
     public String action();
}
完成后将其打包为testInterface.jar文件。

接下来新建一工程,为了编译通过,引入之前打好的testInterface.jar包。并创建TestAction类,使它实现 ActionInterface接口。如下:


public class  TestAction implements ActionInterface {
    public  String action() {
         return " com.mxjava.TestAction.action " ;
    }
}

完成后将其打包为test.jar,放在c盘根目录下。下面要做的就是利用URLClassLoader加载并运行TestAction的action方法,并将返回的值打印在控制台上。

新建一工程,引入testInterface.jar包。并创建一可执行类(main方法),在其中加入如下代码:

URL url = new URL(“file:C: / test.jar”);
URLClassLoader myClassLoader  =   new  URLClassLoader( new  URL[]   { url } );
Class myClass  =  myClassLoader.loadClass(“com.mxjava.TestAction”);
ActionInterface action  =  (ActionInterface)myClass.newInstance();
System.out.println(action.action());
  在上面的例子中,首先利用URLClassLoader加载了C:/test.jar包,将其中的com.mxjava.TestAction类载入内存,将其强制转型为testInterface包中的ActionInterface类型,最后调用其action方法,并打印到控制台中。

  执行程序后,在控制台上如期打印出我们想要的内容。但是,事情并没有那么简单,当我们将该代码移动web应用中时,就会抛出异常。原来,Java为我们提供了三种可选择的ClassLoader:
1. 系统类加载器或叫作应用类加载器 (system classloader or application classloader)
2. 当前类加载器
3. 当前线程类加载器

  在上例中我们使用javac命令来运行该程序,这时候使用的是系统类加载器 (system classloader)。这个类加载器处理 -classpath下的类加载工作,可以通过ClassLoader.getSystemClassLoader()方法调用。 ClassLoader 下所有的 getSystemXXX()的静态方法都是通过这个方法定义的。在代码中,应该尽量少地调用这个方法,以其它的类加载器作为代理。否则代码将只能工作在简单的命令行应用中。当在web应用中时,服务器也是利用ClassLoader来加载class的,由于ClassLoader的不同,所以在强制转型时JVM认定不是同一类型。(在JAVA中,一个类用其完全匹配类名(fully qualified class name)作为标识,这里指的完全匹配类名包括包名和类名。但在JVM中一个类用其全名和一个加载类ClassLoader的实例作为唯一标识。因此,如果一个名为Pg的包中,有一个名为Cl的类,被类加载器KlassLoader的一个实例kl1加载,Cl的实例,即C1.class在JVM中表示为 (Cl, Pg, kl1)。这意味着两个类加载器的实例(Cl, Pg, kl1) 和 (Cl, Pg, kl2)是不同的,被它们所加载的类也因此完全不同,互不兼容的。)为了能够使程序正确运行,我们首要解决的问题就是,如何将 URLClassLoader加载的类,同当前ClassLoader保持在同一类加载器中。解决方法很简单,利用java提供的第三种 ClassLoader—当前线程类加载器即可。jdk api文档就会发现,URLClassLoader提供了三种构造方式:

// 使用默认的委托父 ClassLoader 为指定的 URL 构造一个新 URLClassLoader。 
URLClassLoader(URL[] urls)
// 为给定的 URL 构造新 URLClassLoader。 
URLClassLoader(URL[] urls, ClassLoader parent)
// 为指定的 URL、父类加载器和 URLStreamHandlerFactory 创建新 URLClassLoader。
URLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) 
接下来要做的就是,在构造URLClassLoader时,将当前线程类加载器置入即可。如下:

  URLClassLoader myClassLoader  =   new  URLClassLoader( new  URL[]   { url } , Thread.currentThread().getContextClassLoader());
总结:
  Java是利用ClassLoader来加载类到内存的,ClassLoader本身是用java语言写的,所以我们可以扩展自己的 ClassLoader。利用URLClassLoader可以加载指定jar包中的类到内存。在命行上利用URLClassLoader加载jar时,是使用系统类加载器来加载class的,所以在web环境下,就会出错。这是因为JVM中一个类用其全名和一个加载类ClassLoader的实例作为唯一标识的。我们只要利用URLClassLoader的第二种构造方法并传入当前线程类加载器即可解决。
分享到:
评论

相关推荐

    URLClassLoader中指定目录和jar的问题

    在Java编程语言中,`URLClassLoader`是Java标准类加载器的一种实现,它负责从指定的URL(统一资源定位符)加载类和资源。本文将深入探讨`URLClassLoader`的工作原理,以及如何处理指定目录和JAR文件中的类加载问题。...

    Java URLClassLoader动态加载jar包1

    Java URLClassLoader 是Java标准库中的一个类加载器,它允许我们动态地从指定的URL位置加载类和资源。这个功能在开发插件系统、热部署或者处理多种版本库的场景中非常有用。从JDK 1.2开始,`java.net.URLClassLoader...

    使用URLClassLoader加载本地文件夹c盘下的test.jar文件

    URLClassLoader是Java提供的一种类加载器,它允许我们通过URL来加载类和资源,从而实现这一目标。本篇文章将深入讲解如何使用URLClassLoader加载C盘下的test.jar文件。 首先,了解类加载器的基本概念。在Java中,类...

    Java动态编译Java代码,运行在内存中,并执行

    创建 URLClassLoader 类加载器 * 2.获取当前执行的classpath的所有jar包的路径 * 3.通过java的ToolProvider创建JavaCompile,用来执行class源文件 * 4.创建DiagnosticCollector用来执行获取执行失败的错误结果 *...

    URLClassLoader初体验

    在Java世界中,`URLClassLoader`是一个非常关键的类,它是`ClassLoader`的子类,主要用于从指定的URL(统一资源定位符)加载类和资源。这篇博客文章“URLClassLoader初体验”可能深入探讨了如何使用`URLClassLoader`...

    java反序列化漏洞URLClassLoader利用1

    为了防御这类攻击,开发者应该确保对反序列化的数据进行严格的验证,避免加载不可信的类,同时限制类加载器的权限,特别是对于能够从网络加载类的类加载器,如`URLClassLoader`。 在修复此类漏洞时,可以考虑以下...

    疯狂JAVA讲义

    学生提问:既然内部类是外部类的成员,是否可以为外部类定义子类,在子类中再定义一个内部类来重写其父类中的内部类? 211 6.7.4 局部内部类 211 6.7.5 匿名内部类 212 6.7.6 闭包(Closure)和回调 215 6.8 ...

    JDK7.0新特性

    1. **URLClassLoader.close 方法**:为了更好地管理资源,URLClassLoader 类新增了一个 close 方法,允许开发者关闭URL类加载器并释放相关资源。具体用法参见官方文档《关闭 URLClassLoader》。 2. **...

    Springboot + Hutool-db 使用 URLClassLoader 动态加载外部数据库和数据池 jar包实例

    然而,为了实现动态加载,我们可以使用URLClassLoader,这是一个Java类加载器,它可以加载指定URL路径下的类。通过这种方式,我们可以在运行时动态地将新的数据库驱动jar包引入到类路径中,从而允许应用程序连接到新...

    Spring Boot 的java -jar命令启动原理详解

    这个类加载器通过重写URLClassLoader类的几个方法,能够从JAR文件的特殊目录结构中加载类和资源。当执行java -jar命令时,实际上是由org.springframework.boot.loader.JarLauncher类来启动整个应用。 JarLauncher会...

    ClassLoaderTest:测试如何正确关闭类加载器,以便可以关闭基础jar文件上的文件句柄

    当我们使用自定义的URLClassLoader时,尤其需要注意类加载器的生命周期管理,因为不正确的关闭可能导致打开的文件句柄无法正确释放,从而消耗系统资源。 首先,我们来了解下类加载器的工作原理。Java中的类加载器...

    Java 自动加载JAR文件并运行其中的类方法

    使用`URLClassLoader`,我们可以动态地将JAR文件添加到当前的类路径中。示例代码如下: ```java File jarFile = new File("path_to_your_jar.jar"); URL url = jarFile.toURI().toURL(); URL[] urls = new URL...

    java类加载机制原理与实现

    然而,双亲委派机制也可以被破坏,例如使用 URLClassLoader 加载类,这可以使得类加载器不遵守双亲委派机制的规则。 在 Java 中,了解类加载机制非常重要,因为它关系到 Java 程序的执行和安全性。理解类加载机制...

    动态加载类机制JAVA

    - 当类位于非标准的类路径,如网络服务器或特定文件系统位置时,可以使用`URLClassLoader`。它允许自定义类路径,从而能从不同的URL加载类。 5. 引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ...

    动态编译、加载java类

    通过创建`URLClassLoader`实例并传入包含源码或编译后类的目录或JAR文件的URL,可以在运行时加载新编译的类。 4. **反射(Reflection)**: 在Java中,反射API允许程序在运行时检查和操作类、接口、字段和方法的信息...

    Java虚拟机JVM类加载初始化

    - 网络加载:使用`java.net.URLClassLoader`从网络指定的URL加载类。 - 压缩文件加载:从`.jar`、`.zip`等压缩文件中查找并加载类,自动解析`.jar`文件中的`.class`文件。 - 动态编译:从`.java`源代码文件编译成...

    Java类加载原理解析文档

    在标准扩展类加载器和系统类加载器的实现中,可以看到它们都继承自`URLClassLoader`和`SecureClassLoader`,但并没有重写`ClassLoader`的`loadClass()`方法,而是按照双亲委派模式执行。这样,类加载器们可以在保证...

    lassLoader的关系以及如何防止ClassLoader内存泄漏

    在Java世界中,类加载器(ClassLoader)是关键的组件之一,它负责将类的字节码文件(.class)从文件系统或网络中加载到Java虚拟机(JVM)中,使得程序能够运行。本篇文章将深入探讨ClassLoader的关系网络以及如何...

    反射获取jar文件中的类

    这个方法使用了 JarFile 和 JarEntry 来获取 jar 文件中的所有类,然后使用 URLClassLoader.loadClass 方法加载类,并使用 getMethods 方法获取类中的方法。 反射的应用 反射机制有很多应用,例如: * 动态代理:...

    JAVA 类加载机制分析

    自定义类加载器(Custom ClassLoader)允许开发人员扩展加载类的行为,例如使用`URLClassLoader`从指定的URL加载类。类加载的层次结构(hierarchy)从引导类加载器开始,然后是扩展类加载器(ExtClassLoader),最后...

Global site tag (gtag.js) - Google Analytics