设为首页 加入收藏

TOP

一次 Maven 事故
2018-01-09 06:06:35 】 浏览:267
Tags:一次 Maven 事故

改动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的同名文件而不会读取你项目中的。但是这样确是松耦合的。
目前还没有找到好的方法,最小程度上改动代码,增加或删除一些东西。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java 回顾 ( Revisiting Java ) 下一篇使用 yaml+groovy 实现 Java 代码..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目