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

简介: 动态加载jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行。 下面通过一个实例来直观演示: 第一:定义一个抽象类 AbstractAction (稍后换成接口的实例)   [java] view plain copy     package com.

动态加载jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行。

下面通过一个实例来直观演示:

第一:定义一个抽象类 AbstractAction (稍后换成接口的实例)

 

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.java.loader;  
  2.   
  3. public abstract class AbstractAction {  
  4.     public abstract String action();  
  5. }  

第二:写个实体类继承一下 TestAction

 

 

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.java.jarloader;  
  2.   
  3. import com.java.loader.AbstractAction;  
  4.   
  5. public class TestAction extends AbstractAction{  
  6.     public String action() {  
  7.         System.out.println("I am working ! ");  
  8.         return "this ActionTest class";  
  9.     }  
  10. }  

第三:将TestAction所在的包导出成jar包的方式,eclipse中直接export即可,放到指定目录,此处放在

 

 

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. D:\jarload\test.jar  


放好后,删除TestAction文件和package。

 

第四:写个main函数测试下 TestMain (这里比较无聊,写了个从文件读的方式获取jar路劲,路径就是上面提到的jar所在的位置)

 

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.java.main;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.File;  
  5. import java.io.FileReader;  
  6. import java.net.URL;  
  7. import java.net.URLClassLoader;  
  8.   
  9. import com.java.loader.AbstractAction;  
  10. import com.java.loader.AbstractAction;  
  11.   
  12.   
  13. /** 
  14.  *  
  15.  * 两种方式 
  16.  * @author minggang.wumg 
  17.  * 
  18.  */  
  19.   
  20. public class TestMain {  
  21.   
  22.     public static void main(String[] args) {  
  23.         try {  
  24.             //第一种  配置成文件格式  
  25.             File file = new File("D:\\jarload\\test.txt");  
  26.             BufferedReader in = new BufferedReader(new FileReader(file));  
  27.             String s = new String();  
  28.             while ((s = in.readLine()) != null) {  
  29.   
  30.                 URL url = new URL(s);  
  31.                 s = null;  
  32.                   
  33.                 URLClassLoader myClassLoader = new URLClassLoader(new URL[] { url }, Thread.currentThread()  
  34.                         .getContextClassLoader());  
  35.                 Class<? extends AbstractAction> myClass = (Class<? extends AbstractAction>) myClassLoader.loadClass("com.java.jarloader.TestAction");  
  36.                 AbstractAction action = (AbstractAction) myClass.newInstance();  
  37.                 String str = action.action();  
  38.                 System.out.println(str);  
  39.                   
  40.                 //第二种  
  41.                 URL url1 = new URL("file:D:/jarload/test.jar");  
  42.                 URLClassLoader myClassLoader1 = new URLClassLoader(new URL[] { url1 }, Thread.currentThread()  
  43.                         .getContextClassLoader());  
  44.                 Class<?> myClass1 = myClassLoader1.loadClass("com.java.jarloader.TestAction");  
  45.                 AbstractAction action1 = (AbstractAction) myClass1.newInstance();  
  46.                 String str1 = action1.action();  
  47.                 System.out.println(str1);  
  48.             }  
  49.         } catch (Exception e) {  
  50.             e.printStackTrace();  
  51.         }  
  52.     }  
  53.   
  54. }  


第五:运行结果:

 

这是能完成运行的!

下面我们来改写下:

第一:将抽象类改成接口的形式  InterfaceAction 

 

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.java.loader;  
  2.   
  3. public interface InterfaceAction {  
  4.     public String action();  
  5. }  

第二:改写下实体类,实现接口 TestAction

 

 

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.java.jarloader;  
  2.   
  3. import com.java.loader.InterfaceAction;  
  4.   
  5. public class TestAction implements InterfaceAction{  
  6.   
  7.     @Override  
  8.     public String action() {  
  9.         System.out.println("I am working ! ");  
  10.         return "this ActionTest class";  
  11.     }  
  12.   
  13. }  


第三步相同。

 

第四步:稍作修改 TestMain

 

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.java.main;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.File;  
  5. import java.io.FileReader;  
  6. import java.net.URL;  
  7. import java.net.URLClassLoader;  
  8.   
  9. import javax.swing.AbstractAction;  
  10.   
  11. import com.java.loader.InterfaceAction;  
  12.   
  13.   
  14.   
  15.   
  16. /** 
  17.  *  
  18.  * 两种方式 
  19.  * @author minggang.wumg 
  20.  * 
  21.  */  
  22.   
  23. public class TestMain {  
  24.   
  25.     public static void main(String[] args) {  
  26.         try {  
  27.             //第一种  配置成文件格式  
  28.             File file = new File("D:\\jarload\\test.txt");  
  29.             BufferedReader in = new BufferedReader(new FileReader(file));  
  30.             String s = new String();  
  31.             while ((s = in.readLine()) != null) {  
  32.   
  33.                 URL url = new URL(s);  
  34.                 s = null;  
  35.                   
  36.                 URLClassLoader myClassLoader = new URLClassLoader(new URL[] { url }, Thread.currentThread()  
  37.                         .getContextClassLoader());  
  38.                 Class<?> myClass = (Class<?>) myClassLoader.loadClass("com.java.jarloader.TestAction");  
  39.                 InterfaceAction action = (InterfaceAction) myClass.newInstance();  
  40.                 String str = action.action();  
  41.                 System.out.println(str);  
  42.                   
  43.                 //第二种  
  44.                 URL url1 = new URL("file:D:/jarload/test.jar");  
  45.                 URLClassLoader myClassLoader1 = new URLClassLoader(new URL[] { url1 }, Thread.currentThread()  
  46.                         .getContextClassLoader());  
  47.                 Class<?> myClass1 = myClassLoader1.loadClass("com.java.jarloader.TestAction");  
  48.                 InterfaceAction action1 = (InterfaceAction) myClass1.newInstance();  
  49.                 String str1 = action1.action();  
  50.                 System.out.println(str1);  
  51.             }  
  52.         } catch (Exception e) {  
  53.             e.printStackTrace();  
  54.         }  
  55.     }  
  56.   
  57. }  


第五:运行结果相同。

 

转自http://blog.csdn.net/wawmg/article/details/17961815

作者:Bonker
出处:http://www.cnblogs.com/Bonker
QQ:519841366
       
本页版权归作者和博客园所有,欢迎转载,但未经作者同意必须保留此段声明, 且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利
目录
相关文章
|
3天前
|
存储 安全 算法
Java容器及其常用方法汇总
Java Collections框架提供了丰富的接口和实现类,用于管理和操作集合数据。
Java容器及其常用方法汇总
|
5天前
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
21 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
3天前
|
Java API
java.time常用方法汇总
`java.time` API 是从 Java 8 开始引入的时间日期处理库,旨在替代老旧的 `java.util.Date` 和 `Calendar`。它提供了更简洁、强大和灵活的方式处理日期、时间、时区及时间间隔,支持全球化和时间计算需求。API 包含获取当前时间、创建指定时间、解析和格式化字符串、进行加减运算、比较时间、获取年月日时分秒、计算时间间隔、时区转换以及判断闰年等功能。示例代码展示了如何使用这些功能,极大简化了开发中的时间处理任务。
|
6天前
|
安全 Java 编译器
JAVA泛型类的使用(二)
接上一篇继续介绍Java泛型的高级特性。3. **编译时类型检查**:尽管运行时发生类型擦除,编译器会在编译阶段进行严格类型检查,并允许通过`extends`关键字对类型参数进行约束,确保类型安全。4. **桥方法**:为保证多态性,编译器会生成桥方法以处理类型擦除带来的问题。5. **运行时获取泛型信息**:虽然泛型信息在运行时被擦除,但可通过反射机制部分恢复这些信息,例如使用`ParameterizedType`来获取泛型参数的实际类型。
|
6天前
|
安全 Java 编译器
JAVA泛型类的使用(一)
Java 泛型类是 JDK 5.0 引入的重要特性,提供编译时类型安全检测,增强代码可读性和可维护性。通过定义泛型类如 `Box&lt;T&gt;`,允许使用类型参数。其核心原理是类型擦除,即编译时将泛型类型替换为边界类型(通常是 Object),确保与旧版本兼容并优化性能。例如,`Box&lt;T&gt;` 编译后变为 `Box&lt;Object&gt;`,从而实现无缝交互和减少内存开销。
|
7天前
|
前端开发 JavaScript Java
Java打包jar运行时分离lib和jar
在`pom.xml`的`build`节点中,设置`packaging`为`jar`,并配置插件分离依赖库到`lib`目录和资源文件到`resources`目录。这样可以在运行时通过`-Dloader.path=lib,resources`加载外部依赖和资源文件,便于独立升级依赖库和修改资源文件,而无需重新打包程序。具体插件包括`maven-dependency-plugin`、`maven-resources-plugin`和`spring-boot-maven-plugin`等。
44 1
|
22天前
|
Java 程序员 调度
Java 高级面试技巧:yield() 与 sleep() 方法的使用场景和区别
本文详细解析了 Java 中 `Thread` 类的 `yield()` 和 `sleep()` 方法,解释了它们的作用、区别及为什么是静态方法。`yield()` 让当前线程释放 CPU 时间片,给其他同等优先级线程运行机会,但不保证暂停;`sleep()` 则让线程进入休眠状态,指定时间后继续执行。两者都是静态方法,因为它们影响线程调度机制而非单一线程行为。这些知识点在面试中常被提及,掌握它们有助于更好地应对多线程编程问题。
55 9
|
7月前
|
Java
[JarEditor]可直接修改jar包的IDEA插件
### 修改JAR包变得更简单:JarEditor插件简介 **背景:** 开发中常需修改JAR包中的class文件,传统方法耗时费力。JarEditor插件让你一键编辑JAR包内文件,无需解压。 **插件使用:** 1. **安装:** 在IDEA插件市场搜索JarEditor并安装。 2. **修改class:** 打开JAR文件中的class,直接编辑,保存后一键构建更新JAR。 3. **文件管理:** 右键菜单支持在JAR内新增/删除/重命名文件等操作。 4. **搜索:** 使用内置搜索功能快速定位JAR包内的字符串。
645 2
[JarEditor]可直接修改jar包的IDEA插件
|
7月前
|
弹性计算 Java Serverless
Serverless 应用引擎操作报错合集之上传自定义JAR包,启动时报错,是什么导致的
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
7月前
|
关系型数据库 Java 分布式数据库
PolarDB产品使用问题之部署到服务器上的Java应用(以jar包形式运行)无法连接,如何解决
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。

热门文章

最新文章