如何运行jar文件(如何打开jar文件?)

抒情君 6

导读:在实际项目开发中,有时会遇到需动态加载jar包的应用场景。如将Flink的UDF自定义方法制作成方法库(既打成一个Jar),在提交给Flink集群的Job中动态加载jar便可使用。下面将举一个简单实现Java动态加载Jar的案列。

环境准备动态加载Jar实现解析与拓展

环境准备

为了便于实现Demo,这里构建一个模块化Maven项目dynamicloading,项目包含:dyna-loading-function方法库模块、dyna-loading-core核心模块。

在dyna-loading-function中编写方法

编写一个方法抽象类,及一个实现类Split,class

/** * 方法抽象类 */publicabstractclassAbstractFunction {publicabstractvoideval(Strings); }/** * 字符串截取方法 */publicclassSplitextendsAbstractFunction {@Overridepublicvoideval(Strings) { System.out.println("对字符串"+s+"进行截取操作"); } }

将dyna-loading-function打成Jar包

在dyna-loading-core模块实现动态加载Jar

importjava.io.File;importjava.lang.reflect.Method;importjava.net.URL;importjava.net.URLClassLoader;publicclassdynaLoadTest {publicstaticvoidmain(String[] args) throws Exception{//jar所在路径StringjarPath ="C:\repo\com\wxb\dyna-loading-function\1.0-SNAPSHOT\dyna-loading-function-1.0-SNAPSHOT.jar"; loadJar(jarPath);//利用反射Class aClass = Class.forName("function.Split");Objectinstance = aClass.newInstance();//调用方法aClass.getDeclaredMethod("eval",String.class).invoke(instance,"hello word"); }//动态加载JarpublicstaticvoidloadJar(StringjarPath) { File jarFile =newFile(jarPath);//文件存在if(jarFile.exists() ==false) { System.out.println("jar file not found.");return; }//从URLClassLoader类加载器中获取类的addURL方法Method method =null;try{ method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); }catch(NoSuchMethodException | SecurityException e1) { e1.printStackTrace(); }// 获取方法的访问权限booleanaccessible = method.isAccessible();try{//修改访问权限为可写if(accessible ==false) { method.setAccessible(true); }// 获取系统类加载器URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();//获取jar文件的url路径URL url = jarFile.toURI().toURL();//jar路径加入到系统url路径里method.invoke(classLoader, url); }catch(Exception e) { e.printStackTrace(); }finally{ method.setAccessible(accessible); } } }

运行

解析与拓展

ClassLoader是类加载器,其具体作用就是将class文件加载到jvm虚拟机中去,程序就可以正确运行了。java程序运行的时候,类必须被加载到jvm虚拟机中才可以正常使用。但不是所有的class文件都在启动的时候全部加载,根据资料java最早就是为嵌入式系统而设计的,内存宝贵。如果开始时就把所有类都加载到jvm中,有些class可能在整个运行过程中都不会被用到,这样便会占用宝贵的内存。因此启动时会先把保证程序运行的基础类一次性加载到jvm中,其它class等到jvm用到的时候再通过动态加载将其加载到jvm虚拟中。

Java中内置了很多的类加载器,而ClassLoader是所有类加载器的基类,它是个抽象类,其定义了类加载最核心的操作。因本文主题是动态加载Jar,所以下面我们主要讨论URLClassLoader。

URLClassLoader

URLClassLoader继承自SecureClassLoader,支持从jar文件和文件夹中获取class。而SecureClassLoader继承于ClassLoader。

核心代码:

//1、通过getDeclaredMethod获取URLClassLoader的addURL,这一步的目的是为了设置addURL方法可写Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);method.setAccessible(true);//2、获取 URLClassLoader加载器URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();//3、获取目标jar的URLURL url = jarFile.toURI().toURL();//4、执行addURL方法,通过URLclassLoader从指定jar中获取class并动态加到jvm虚拟机里method.invoke(classLoader, url);//5、class成功被动态加载进虚拟机后,就可以利用反射获取Class aClass = Class.forName("function.Split");

最后

感谢您的阅读,如果喜欢本文欢迎关注和转发,本头条号将坚持原创,持续分享IT技术知识。对于文章内容有其他想法或意见建议等,欢迎提出共同讨论共同进步

上一篇:

下一篇:

  推荐阅读

分享