java项目动态加载外部jar,调用其中类方法
一,背景
项目需要通过加载外部jar文件更新某项功能
1,这是ServiceImpl中的方法摘取,
处理业务:
简单点来说就是:接收前端上传的jar文件和请求数据,通过调用上传的jar文件中的类方法对请求数据做处理(实现动态加载)
/** * 这是ServiceImpl中的方法摘取 * * @param abilityContributionStructDataReq 请求数据 * @param file jar文件 * @return * @Author zl */ @Override public Double dynamicLoad(String abilityContributionStructDataReq, MultipartFile file) throws IOException { //上传文件不能为空 if (file == null) { throw new CustomException("动态计算lib库不能为空"); } //这就是一个封装的文件上传返回文件路径的方法 String textUrl = FileUtil.uploadText(file); //jar文件 File fileJar = new File(textUrl); URLClassLoader urlClassLoader = null; Class<?> mytest = null; String substring = null; if (file.getOriginalFilename() != null) { substring = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.') + 1); } //jar包校验 if (!"jar".equals(substring)) { throw new CustomException("只能上传“.jar”文件"); } try { //通过URLClassLoader加载外部jar urlClassLoader = new URLClassLoader(new URL[]{new URL("file:" + fileJar.getAbsolutePath())}); //获取外部jar里面的具体类对象 mytest = urlClassLoader.loadClass("jsyc.CalculateAbilityContribution"); //创建对象实例 Object instance = mytest.newInstance(); //获取实例当中的方法名为calculate,参数只有一个且类型为String的public方法 Method method = mytest.getMethod("calculate", String.class); //传入实例以及方法参数信息执行这个方法 String ada = (String) method.invoke(instance, abilityContributionStructDataReq); TechOneAbilityContributionInputOutcomeData abilityContributionInputOutcomeData = JSON.parseObject(ada, TechOneAbilityContributionInputOutcomeData.class); coreApi.getInputOutcomeData().getAbilityContributionModuleDataMgr().saveData(abilityContributionInputOutcomeData); System.out.println(ada); return 0.0; } catch (Exception e) { throw new CustomException("计算出错,请导入正确动态计算库"); } finally { //卸载关闭外部jar try { urlClassLoader.close(); } catch (IOException e) { System.out.println("关闭外部jar失败:" + e.getMessage()); } } }
二,一般情况下,我们动态加载的jar可能会引用第三方依赖,这里存在很多坑
一般情况下,我们动态加载的lib库的类名和方法,都是通过配置文件配置,也可以约束死
方法参数和返回值就像前后端接口一样要约束好
1,我这边主项目动态加载的jar文件都是我们自己设计的,我们已经在主项目里面添加了其相应的依赖,在编译器中启动项目操作前端页面没有任何问题,但是部署服务器就抛异常,
我们编写的jar用到了alibaba的json,找不到异常
2,其实说到底还是编写jar文件打包的问题,需要把第三方依赖也打进去
我们现在把java代码打包有许多中方式:
1,jar -cvf my.jar jsyc #通过命令行,将文件夹jsyc下面所有的class文件打成jar包(不包括依赖)
2,通过编译器,普通maven项目,package打包(也不包含依赖)
3,build artifacts(包含依赖) 步骤如下:
打包成功的jar:
心有所想,必有回响