转载自http://blog.csdn.net/mousebaby808/article/details/31788325

概述

  诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下的jar文件以及classes目录下的class文件,另外像spring这类框架,也可以根据指定的路径扫描并加载指定的类文件,这个技术可以实现一个容器,容纳各类不同的子应用。
  Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,不像C加载动态链接库只要一个文件名就可以搞定,但JDK仍提供了一整套方法来动态加载jar文件和class文件。
 

动态加载jar文件

  1. // 系统类库路径
  2. File libPath = new File(jar文件所在路径);
  3. // 获取所有的.jar和.zip文件
  4. File[] jarFiles = libPath.listFiles(new FilenameFilter() {
  5. public boolean accept(File dir, String name) {
  6. return name.endsWith(".jar") || name.endsWith(".zip");
  7. }
  8. });
  9. if (jarFiles != null) {
  10. // 从URLClassLoader类中获取类所在文件夹的方法
  11. // 对于jar文件,可以理解为一个存放class文件的文件夹
  12. Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
  13. boolean accessible = method.isAccessible();     // 获取方法的访问权限
  14. try {
  15. if (accessible == false) {
  16. method.setAccessible(true);     // 设置方法的访问权限
  17. }
  18. // 获取系统类加载器
  19. URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
  20. for (File file : jarFiles) {
  21. URL url = file.toURI().toURL();
  22. try {
  23. method.invoke(classLoader, url);
  24. LOG.debug("读取jar文件[name={}]", file.getName());
  25. } catch (Exception e) {
  26. LOG.error("读取jar文件[name={}]失败", file.getName());
  27. }
  28. }
  29. } finally {
  30. method.setAccessible(accessible);
  31. }
  32. }

动态加载class文件

  1. // 设置class文件所在根路径
  2. // 例如/usr/java/classes下有一个test.App类,则/usr/java/classes即这个类的根路径,而.class文件的实际位置是/usr/java/classes/test/App.class
  3. File clazzPath = new File(class文件所在根路径);
  4. // 记录加载.class文件的数量
  5. int clazzCount = 0;
  6. if (clazzPath.exists() && clazzPath.isDirectory()) {
  7. // 获取路径长度
  8. int clazzPathLen = clazzPath.getAbsolutePath().length() + 1;
  9. Stack<File> stack = new Stack<>();
  10. stack.push(clazzPath);
  11. // 遍历类路径
  12. while (stack.isEmpty() == false) {
  13. File path = stack.pop();
  14. File[] classFiles = path.listFiles(new FileFilter() {
  15. public boolean accept(File pathname) {
  16. return pathname.isDirectory() || pathname.getName().endsWith(".class");
  17. }
  18. });
  19. for (File subFile : classFiles) {
  20. if (subFile.isDirectory()) {
  21. stack.push(subFile);
  22. } else {
  23. if (clazzCount++ == 0) {
  24. Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
  25. boolean accessible = method.isAccessible();
  26. try {
  27. if (accessible == false) {
  28. method.setAccessible(true);
  29. }
  30. // 设置类加载器
  31. URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
  32. // 将当前类路径加入到类加载器中
  33. method.invoke(classLoader, clazzPath.toURI().toURL());
  34. } finally {
  35. method.setAccessible(accessible);
  36. }
  37. }
  38. // 文件名称
  39. String className = subFile.getAbsolutePath();
  40. className = className.substring(clazzPathLen, className.length() - 6);
  41. className = className.replace(File.separatorChar, '.');
  42. // 加载Class类
  43. Class.forName(className);
  44. LOG.debug("读取应用程序类文件[class={}]", className);
  45. }
  46. }
  47. }
  48. }

  完成上述两步操作后,即可使用Class.forName来加载jar中或.class文件包含的Java类了。

[转载] Java中动态加载jar文件和class文件的更多相关文章

  1. Java_Java中动态加载jar文件和class文件

    转自:http://blog.csdn.net/mousebaby808/article/details/31788325 概述 诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下 ...

  2. 【Android】Android动态加载Jar、APK的实现

    本文介绍Android中动态加载Jar.APK的实现.而主要用到的就是DexClassLoader这个类.大家都知道Android和普通的Java虚拟机有差别,它只能加载经过处理的dex文件.而加载这 ...

  3. Java从Jar文件中动态加载类

    动态加载jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行. 下面通过一个实例来直观演示: 第一: ...

  4. Java动态加载jar及class文件

    经常碰到需要动态加载jar及class文件的场景.Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,但JDK仍提供了一整套方法来动态加载jar文件和class文件. 一.动态加载ja ...

  5. java动态加载jar文件

    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, Invo ...

  6. java动态加载jar包,并运行其中的类和方法

    动态加载jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行. 下面通过一个实例来直观演示: 第一: ...

  7. JAVA动态加载JAR包的实现

    如何动态的加载这些驱动!不可能把所有的数据库驱动都集成到JAR包中吧?!于是动态加载驱动的JAR包就产生了!其实这些在做系统基础代码时,经常用到,只是一般我们没有机会去搞而已. 动态加载JAR包,使用 ...

  8. 某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法

    在某APK中,通过如下方法动态注册了一个BroadcastReceiver,代码参考如下: @Override protected void onAttachedToWindow() { super. ...

  9. Android动态加载jar/dex

    前言 在目前的软硬件环境下,Native App与Web App在用户体验上有着明显的优势,但在实际项目中有些会因为业务的频繁变更而频繁的升级客户端,造成较差的用户体验,而这也恰恰是Web App的优 ...

随机推荐

  1. C-一行或多行文章垂直居中

    1 样式效果 2 table布局 li span 

  2. 虚拟机+桥接模式+Host-only模式 搭建完美的Windows下Linux开发环境

    相信有很多鞋童和我一个样是一枚Linux码农(我现在还是嵌入式方向). 做Linux开发势必需要一个Linux环境, 大多数开发者会首先选择一个Linux发行版, 其中Ubuntu LTS版本应该是选 ...

  3. 【特效】hover效果之四线动画

    效果预览:http://www.gbtags.com/gb/rtreplayerpreview-standalone/3102.htm html: <div class="wrap&q ...

  4. linux 远程操作(expect)

    Expect是在Tcl基础上创建起来的,它还提供了一些Tcl所没有的命令,它可以用来做一些linux下无法做到交互的一些命令操作,在远程管 理方面发挥很大的作用. spawn命令激活一个Unix程序来 ...

  5. 三种方式设置特定设备UWP XAML view

    开发者可以设置UWP特定设备xaml view,在桌面,手机,Iot,这个对于设置对不同设备的不同屏幕有用.我们可以使用RelativePanel,VisualStateTriggers,但是这样我们 ...

  6. PHP知识大全

    --------------------------------------------------------- PHP知识大全 ---------------------------------- ...

  7. 用 Smali 手写一个可运行的 HelloWorld!!!

    一.前言 Android 的 App 实际上并不是运行在 Java 虚拟机中,而是运行在 Dalvik 虚拟机中.Dalvik 虚拟机对 Java 虚拟机做了一些额外的优化,让它更适用于移动设备.而 ...

  8. IOS 中的JS

     文章摘自: http://www.cocoachina.com/ios/20150127/11037.html  JSContext/JSValue JSContext 即JavaScript代码的 ...

  9. CodePath Android CliffNotes 之 Effective Java for Android 翻译

    概述: 这篇文章的目的是作为这篇博文的开源版本,而netcyrax是该指南的原始文章的唯一作者. 请在下面添加您自己的在Android中Java最佳实践.技巧和巧妙! 建造者模式 当你拥有一个需要超过 ...

  10. MAC 下虚拟主机的配置

    第一部分:httpd.conf 1:找到这段,改成如下这样 <Directory /> Options Indexes FollowSymLinks AllowOverride All O ...