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:

 

 

 

 
        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM