一,背景
項目需要通過加載外部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: