java程序中动态加载jar包并执行
2016-07-20 11:35
330 查看
参考了几篇文章
加载jar包的类URLClassLoader中使用的方法为addURL,但是这个方法是protected类型
分别用了两种方法
一、
参考 http://blog.csdn.net/ozwarld/article/details/7440937
反射到这个类
然后再执行add加载jar包,之后再次反射获取需要执行的类
最开始使用的是下面的方法,感觉简单,但是由于没设置parentClassLoader,导致出现各种bug,最后虽然调通了,但是依然选择了上面的方法(不确定是否还有其他问题)
二、
参考的http://www.cnblogs.com/flyingzl/articles/3139028.html
文章中先建立个子类,这样可以执行addURL这个方法了
加载jar,并执行
另、
如果是本地jar的话,这样就ok了,在hdfs上的话,会有点问题,URL不支持hdfs协议
这样就支持hdfs协议了,path就可以转url了,当然,得加载下hdfs相关配置文件,获取FileSystem实例
只运行普通jar的话,在hdfs上是可以的
但是
如果加载的是mapreduce程序的jar包,只能是本地路径,不能使用hdfs路径,在setJarByClass方法中,是需要寻找到jar包绝对路径的
----------------------------------------------
使用一段时间后发现,进程是不停的,需要加载的jar包是可能需要修改的,所以导致多次加载不同版本的jar包之后,程序会有bug,读不到最新的jar包,不太可能更新jar包就重启下程序
于是,又研究了下classloarder,在当前线程加载jar包比较保险,线程结束会释放掉,保证每次加载都是最新的,而且也不占内存
(URLClassLoader)ClassLoader.getSystemClassLoader(); 改为当前线程类加载器
(URLClassLoader)Thread.currentThread().getContextClassLoader();
加载jar包的类URLClassLoader中使用的方法为addURL,但是这个方法是protected类型
分别用了两种方法
一、
参考 http://blog.csdn.net/ozwarld/article/details/7440937
反射到这个类
Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class }); add.setAccessible(true);
然后再执行add加载jar包,之后再次反射获取需要执行的类
URLClassLoader classloader = (URLClassLoader)ClassLoader.getSystemClassLoader(); URL url = new File(jarPath).toURI().toURL(); add.invoke(classloader, new Object[] { url }); Class<?> clazz = Class.forName(className); Method method = clazz.getDeclaredMethod("xxxx"); method.invoke(clazz.newInstance());
最开始使用的是下面的方法,感觉简单,但是由于没设置parentClassLoader,导致出现各种bug,最后虽然调通了,但是依然选择了上面的方法(不确定是否还有其他问题)
二、
参考的http://www.cnblogs.com/flyingzl/articles/3139028.html
文章中先建立个子类,这样可以执行addURL这个方法了
static class MyClassLoader extends URLClassLoader { public MyClassLoader(URL[] urls) { super(urls); } public MyClassLoader(URL[] urls, ClassLoader parent) { super(urls, parent); } public void addJar(URL url) { this.addURL(url); } }
加载jar,并执行
URL[] urls = new URL[] {}; MyClassLoader classLoader = new MyClassLoader(urls,ClassLoader.getSystemClassLoader()) try { classLoader.addJar(new File("c:/hello.jar").toURI().toURL()); Class<?> clazz = classLoader.loadClass("pakcagename.classname"); Method method = clazz.getDeclaredMethod("run"); method.invoke(clazz.newInstance()); classLoader.close(); } catch (Exception e) { e.printStackTrace(); }
另、
如果是本地jar的话,这样就ok了,在hdfs上的话,会有点问题,URL不支持hdfs协议
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
这样就支持hdfs协议了,path就可以转url了,当然,得加载下hdfs相关配置文件,获取FileSystem实例
Path path = fs.getFileStatus(new Path(jarPath)).getPath(); URL url = path.toUri().toURL(); classLoader.addJar(url);
只运行普通jar的话,在hdfs上是可以的
但是
如果加载的是mapreduce程序的jar包,只能是本地路径,不能使用hdfs路径,在setJarByClass方法中,是需要寻找到jar包绝对路径的
----------------------------------------------
使用一段时间后发现,进程是不停的,需要加载的jar包是可能需要修改的,所以导致多次加载不同版本的jar包之后,程序会有bug,读不到最新的jar包,不太可能更新jar包就重启下程序
于是,又研究了下classloarder,在当前线程加载jar包比较保险,线程结束会释放掉,保证每次加载都是最新的,而且也不占内存
(URLClassLoader)ClassLoader.getSystemClassLoader(); 改为当前线程类加载器
(URLClassLoader)Thread.currentThread().getContextClassLoader();
相关文章推荐
- spring Model 传递参数的值
- Java设计模式—适配器模式
- Java设计模式—适配器模式
- Spring Data JPA
- java反射获得泛型参数
- myeclipse更改某种后缀文件的打开方式
- 使用JavaMail创建邮件和发送邮件
- 通过JDK自带的wsimport生成jws客户端代码
- Java线程泄露的分析与处理
- 使用springmvc+urlRewrite实现404,500以及异常的处理
- java对象与json对象之间的相互转换
- 解决Setting property 'source' to 'org.eclipse.jst.jee.server的问题
- Spring注解@Component、@Repository、@Service、@Controller区别
- Java 深拷贝与浅拷贝的分析
- eclipse插件:打开选中文件所在的目录
- 【转】 java 运算符优先级
- eclipse结合git和github
- Java的native关键字以及JNI
- Java程序实现导出Excel的方法(支持IE低版本)
- Spring入门案例 注解方式配置(一)