窜改mllib中的org.apache.spark.ml.tree.impl.DTStatsAggregator源码,加了一个本来没有的allStats(): Array[Double] = ..的要领,然后打成MLlib包,替换maven库中的mllib包。
报IllegalAccessError:
Caused by: java.lang.IllegalAccessError: tried to access method org.apache.spark.ml.tree.impl.DTStatsAggregator.allStats()[D from class org.apache.spark.ml.tree.impl.RandomForestImpl$
private[ml] val allStatSize val allStats = new Array[Double](allStatSize)
应该要能会见到
是不是用的不是我的jar,可能用的不是我的jar中的class?
运行jar包时配置
--conf "spark.driver.extraJavaOptions=-XX:+TraceClassLoading -XX:+TraceClassUnloading
监测类的加载环境,公然发明有一条
[Loaded xxx from file:/home/huqiu/programs/spark/jars/spark-mllib_2.11-2.1.0.jar
这说明措施不从我打好的jar包中加载class,而从spark安装目次中的jars目次中读取了。
为什么从spark当地读而不从打好的jar包中读?
为了先办理问题,我把mllib包复制到SPARK_HOME的jars目次中,昆山软件开发,这下总能读到我的jar了吧。
可是又呈现一个问题:
java.lang.NoClassDefFoundError: Could not initialize class org.apache.spark.ml.core.JNAScala$ Caused by: java.lang.ClassNotFoundException: com.sun.jna.Native
本来是没找到jna的Native class,一看,确实没有打入mllib包中,那是什么原因呢?莫非是谁把它exclude掉了?
从头编译一下,发明这么一条:
[INFO] Excluding net.java.dev.jna:jna:jar:4.2.2 from the shared jar.
说白了就是解除了net.java.dev.jna:jna:jar,所以写的代码顶用到Native的城市找不到类。
厥后发明是spark-parent解除的,且删掉spark-parent的exclude的语句也没用,基础原因在于mllib的打包方法不会把其依赖打入mllib的jar包中。
办理的要领就是将此依赖打入mllib中,可是这样就会酿成mllib-jar-with-dependencies,必定不是我们想要的功效。
这就涉及到了代码设计的层面了,一般环境下,不发起直接修改Mllib源码,昆山软件开发,更不要说在Mllib源码中还插手外部包了,这样太紧耦合了,较量发起的要领是本身成立一个project,成立于spark mllib同样的包路径即可,昆山软件开发,然后修改需要修改的文件,但缺点是窜改文件需要更名字,否则系统会读取底层Mllib的同名文件而不会读取你项目中的。可是这样确是松耦合的。
今朝还没有找到好的要领,最小水平上窜改代码,增加或删除一些对象。