• 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:

    
    
    
    心有所想,必有回响
  • 相关阅读:
    yii框架原生代码
    分库分表
    get和post的区别
    echo print() print_r() var_dump()的区别
    cookie 和session 的区别
    memcached 常用命令及使用说明
    解决高并发
    C# 使用NLog记录日志
    CREATE DATABASE permission denied in database 'master'.
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
  • 原文地址:https://www.cnblogs.com/zhulei2/p/15499662.html
Copyright © 2020-2023  润新知