在Flink开发的过程中,很容易遇到的一个问题就是jar包冲突的问题,由于一个Flink应用程序包含有大量的jar包依赖,而Flink本省也同样有许多的jar 包依赖,这两者之间极有可能产生冲突,比如Flink中依赖了某个具体的jar包的版本,而用户程序中极有可能依赖该jar包的一个更新或是更老的版本。而这 两个版本之间极有可能在同一个类的方法接口上存在差异,从而出现依赖冲突导致的运行时异常。
解决这种问题一般有两种办法,一种是直接将冲突的jar包打shaded,这样系统的jar包和用户jar包拥有不同的全限定名,也就不会产生冲突了。另一个方法 是控制类在classpath的顺序,如果一个类在前面加载过后在后面将不再会被加载,但要实现这样的精准控制比较得不容易,因为classpath中jar包顺序的 调整可能会影响到jar包内多个类的加载顺序,因此最简单的办法就是打破双亲委派模型,也就是在加载依赖时不使用双亲委派模型,而是首先尝试加载用户提 供的依赖,这样也能较好的解决问题,Flink中提供了child-first的类加载策略来实现。其具体的实现其实非常之简单,就是首先有一个alwaysParentFirstPatterns 的过滤器判断,因为还是有些内部类和基础类不希望被子加载起篡改。经过这个过滤器的过滤后才会真的打破双亲委派模型,它首先查看类是否已经被加载,如果 没有加载的话,不再先尝试使用parent类加载器去加载,而是直接由自己尝试去加载,通过这种方式扭转了类加载的顺序。