有一个网友看了我的
《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:
flink slotSharingGroup 在本地调试的时候可能会导致程序卡住
flink的侧输出(sideoutput)和OutputTag
阿门1234:
zookeeper的选举机制是如何应对脑裂的
qq_31224021: