相关文章推荐
重情义的羽毛球  ·  DWM ...·  1 年前    · 
风度翩翩的伤疤  ·  datatable select like ...·  1 年前    · 
仗义的炒面  ·  typescript - Argument ...·  2 年前    · 

有一个网友看了我的 《Flink的classLoader加载机制(推测)-- 记一次程序问题中的探索》 这篇文章,向我提问了一个问题,虽然这个问题我没有解决,但是我打算做一个小实验来验证一下解决思路的可行性。问题如下:

得知该朋友已经解决此问题,我只想到了前期思路,后续的class not found问题其实是jobmanager和taskmanager不在一个jvm中导致的,很厉害,学习了。他的文章: https://www.toutiao.com/i6883793897495986691/

因为我现在没有一套随便实验的flink集群,也没有阿里云的oss,所以就只好做个最简单的实验,证明我是可以从远程加载jar包然后使用jar包中的类的。

首先,需要先创建一个maven工程,创建一个类叫做Remote,随便写一个可以打印东西的方法,然后把这个工程打成一个jar包。(当然,如果已经有一个jar包了,那就直接用也行)

然后,在jar包所在的路径下,用python启动一个http服务,命令:  python -m SimpleHTTPServer 8888

最后用下面的代码就可以加载这个jar包并加载里面的类,然后执行类里的方法了。

public class Test {
    public static void main(String[] args) throws MalformedURLException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException {
        URLClassLoader loader = (URLClassLoader) Test.class.getClassLoader();
        // 获取本地jar文件的URL
//        File jarFile = new File("/Users/zgy/IdeaProjects/test/target/maven-thrift-client-0.0.1-SNAPSHOT.jar");
//        URL targetUrl = jarFile.toURI().toURL();
        // 获取远程jar文件的URL
        URL targetUrl = new URL("http://localhost:8888/target/maven-thrift-client-0.0.1-SNAPSHOT.jar");
        // 这个校验是为了避免重复加载的
        boolean isLoader = false;
        for (URL url : loader.getURLs()) {
            if (url.equals(targetUrl)) {
                isLoader = true;
                break;
        // 如果没有加载,通过反射获取URLClassLoader.allURL方法来加载jar包
        if (!isLoader) {
            Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
            add.setAccessible(true);
            add.invoke(loader, targetUrl);
        // 加载指定的class,然后为其创建对象后执行其方法,这些操作都是用反射去做的
        Class<?> remoteClass = loader.loadClass("Remote");
        Object remoteInstance = remoteClass.newInstance();
        Method method = remoteClass.getDeclaredMethod("func");
        method.setAccessible(true);
        System.out.println(method.invoke(remoteInstance));

        URLClassLoader既可以加载本地文件系统的jar包,也可以加载远程jar包。我猜测这些应该使用统一的io来实现的。

        其实这个实验只是说明了URLClassLoader的能力和使用方法,网上有很多参考资料可以做到这个功能。但是这个方法还有一些缺陷,比如在我使用http协议加载远程jar包的时候,加载速度明显比本地要慢很多。这样的话,其实可以考虑加载之前先下载jar包,然后再加载。(如果下载jar包,是否可以直接下载到ext目录下,让jvm的extensionClassLoader去加载这个jar包呢?)

        另外,这个思路需要用反射去调用类和方法,使用起来很麻烦。我一度怀疑自己做的有问题,为啥jvm不需要这么复杂呢?但是仔细一想,jvm在编译期是需要对应的jar包在的,起码对应的接口要有;运行期也是需要有jar包在,加载后直接使用类去运行了。我们这里做的事情,有点像jvm在运行期加载jar包和找到jar包里的类的过程,而不仅仅是在外部调用类和执行类方法。

(1)这篇文章代码很丰富,主题是如何加载jar包,后边的一些功能对于本文章来说不太需要看https://www.cnblogs.com/itboys/p/11011585.html  

(2)最开始看的这篇文章,比较简单,但也胜在简单 https://blog.csdn.net/fd2025/article/details/80538468

背景 有一个网友看了我的《Flink的classLoader加载机制(推测)-- 记一次程序问题中的探索》这篇文章,向我提问了一个问题,虽然这个问题我没有解决,但是我打算做一个小实验来验证一下解决思路的可行性。问题如下: 实验 因为我现在没有一套随便实验的flink集群,也没有阿里云的oss,所以就只好做个最简单的实验,证明我是可以从远程加载jar包然后使用jar包中的类的。 首先,需要先创建一个maven工程,创建一个类叫...   File   file   =   new   File(jar文件全路径);      URL   url   =   file.toURL();      URLClassLoader   loader   =   new   URLClassLoader(new   URL[]   {   url   });      Class   tidyClazz   =
动态加载jar包,在实际开发中经常会需要用到,尤其涉及平台和业务的关系的时候,业务逻辑部分可以独立出去交给业务方管理,业务方只需要提供jar包,就能在平台上运行。 下面通过一个实例来直观演示: 第一:定义一个抽象类AbstractAction (稍后换成接口的实例) package com.java.loader; public abstract class AbstractAction
package com.classloader.test; public class Test { public static void main(String[] args) { try { MyClassLoader.test("file:G:/javaBY/TEST/FBY.jar","com.fby.test.Test"); } catch (Except
加载实践:读取jar包(在B站上视频学习记录) 类加载机制实际上调用了 loadClass() -> findClass() 1、从特定路径jar包读取class(没有打破双亲委派机制,只是读取其他位置的jar包): public class test { public static void main(String[] args) throws MalformedURLException { Double salary = 2000.0; Double m
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.Malform... 在开发过程中,有时候需要根据配置,动态的加载本地、远程jar包到当前的jvm中,代码实现如下: LoadJarUtil类: import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ...
Jar包冲突之URLClassLoader加载指定jarJar包冲突场景Jar包冲突解决解决方案一解决方案二解决方案三解决方案四总结 Jar包冲突场景 最近项目中用到了SM4加密,发现 bcprov-jdk15on-1.59.jar 和 BJCA-JCE2.jar 两个jar包中存在有两个包路径相同的类: import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; 在某些项目中会使用插件化技术实现一些动态“插拔”或热更新的功能。一般的做法是,定义一个标准接口,然后将实现分离进行独立部署或更新。 现在有个场景,系统希望引入一些特殊的业务“函数”,并支持热更新。来看看我们是怎么实现的。 业务函数接口:IFunction.java /** 业务函数接口 **/ public interface IFunction { /** 函数名称 **/ public String getName(); /** 函数描述 **/ 用户将自己写的java代码打成jar包,然后在A项目的前端页面上上传,后台会将jar包通过http方式上传到B项目。 现在有个需求是:A项目某业务逻辑会用到B项目的jar包,执行其中的方法并拿到方法返回结果。 需求的难点在于: A项目如何远程执行B项目中jar包中的方法呢? URLClassLoader远程加载 java中提供了URLClassLoader类来加载外部jar,并可以执行其中的方法, 参考 记录——JAVA动态加载外部JAR,并调用方法以及卸载关闭打开的外部JAR。 这篇博文介绍
( SELECT SUBJECT, MAX( score ) AS score FROM score GROUP BY SUBJECT ) a LEFT JOIN score b ON a.SUBJECT = b.SUBJECT AND a.score = b.score sql查询成绩表中每一科成绩最高的分数以及这个学生的名字,学科名 小刀617: 老哥,今天网上看到这种题目,我直接用SELECT `subject`,MAX(score) socre ,`name` FROM student GROUP BY `subject`。然后答案不正确,直到看见了你说:(如果你认为是成功的是因为对group by理解的不够,因为在select指定的字段要么就要包含在Group By语句的后面,作为分组的依据;要么就要被包含在聚合函数中)。瞬间醍醐灌顶!然后去看了group by的语法,确实理解不够,老哥写的可以! flink slotSharingGroup 在本地调试的时候可能会导致程序卡住 jobmanager资源不足。不同的分组,不同的slot。设置并行度小一点即可 flink的侧输出(sideoutput)和OutputTag 阿门1234: 可以传,看源码 zookeeper的选举机制是如何应对脑裂的 qq_31224021: zookeeper是CP原则,如果和其他slave失去联系,client是不可能和旧的master交互的,必须内部选举出leader才能重新提供服务