spark在idea中本地如何運行?
前幾天嘗試使用idea在本地運行spark+scala的程序,出現了問題,http://www.cnblogs.com/yjf512/p/7662105.html 當時還以為是本地spark安裝問題,今天發現原來不是。記錄如下:
現象
使用pom寫了一個程序,發現出現下面的錯誤
17/10/12 17:09:43 INFO storage.DiskBlockManager: Created local directory at /private/var/folders/bv/0tp4dw1n5tl9cxpc6dg2jy180000gp/T/blockmgr-0b0bf3cf-dd77-4bb4-97dc-60d6a65a35ae
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.apache.spark.storage.DiskBlockManager.addShutdownHook(DiskBlockManager.scala:147)
at org.apache.spark.storage.DiskBlockManager.<init>(DiskBlockManager.scala:54)
at org.apache.spark.storage.BlockManager.<init>(BlockManager.scala:78)
at org.apache.spark.SparkEnv$.create(SparkEnv.scala:365)
at org.apache.spark.SparkEnv$.createDriverEnv(SparkEnv.scala:193)
at org.apache.spark.SparkContext.createSparkEnv(SparkContext.scala:288)
at org.apache.spark.SparkContext.<init>(SparkContext.scala:457)
at com.didichuxing.scala.BenchMarkMain$.main(BenchMarkMain.scala:21)
at com.didichuxing.scala.BenchMarkMain.main(BenchMarkMain.scala)
Caused by: java.lang.NoSuchFieldException: SHUTDOWN_HOOK_PRIORITY
at java.lang.Class.getField(Class.java:1695)
at org.apache.spark.util.SparkShutdownHookManager.install(ShutdownHookManager.scala:223)
at org.apache.spark.util.ShutdownHookManager$.shutdownHooks$lzycompute(ShutdownHookManager.scala:50)
at org.apache.spark.util.ShutdownHookManager$.shutdownHooks(ShutdownHookManager.scala:48)
at org.apache.spark.util.ShutdownHookManager$.addShutdownHook(ShutdownHookManager.scala:191)
at org.apache.spark.util.ShutdownHookManager$.<init>(ShutdownHookManager.scala:58)
at org.apache.spark.util.ShutdownHookManager$.<clinit>(ShutdownHookManager.scala)
... 9 more
之前以為是我本地沒有安裝spark的問題。后來我的同事使用eclipse可以在本地運行一個spark的程序。於是反思是不是我的項目問題。
看這篇文章https://support.datastax.com/hc/en-us/articles/207038146-DSE-Spark-job-initialisation-returns-java-lang-NoSuchFieldException-SHUTDOWN-HOOK-PRIORITY-
說的是classPath里面的Hadoop的jar包不要使用2.x的,需要使用內置的jar。
打印了classPath,把 /Users/yejianfeng/.m2/repository/org/apache 里面的hadoop文件夾改名了
看了下源碼,大概是說在/Users/yejianfeng/.m2/repository/org/apache/spark/spark-core_2.10/1.6.3/spark-core_2.10-1.6.3-sources.jar!/org/apache/spark/util/ShutdownHookManager.scala
下面有個代碼:
Try(Utils.classForName("org.apache.hadoop.util.ShutdownHookManager")) match {
case Success(shmClass) =>
val fsPriority = classOf[FileSystem]
.getField("SHUTDOWN_HOOK_PRIORITY")
.get(null) // static field, the value is not used
.asInstanceOf[Int]
val shm = shmClass.getMethod("get").invoke(null)
shm.getClass().getMethod("addShutdownHook", classOf[Runnable], classOf[Int])
.invoke(shm, hookTask, Integer.valueOf(fsPriority + 30))
case Failure(_) =>
Runtime.getRuntime.addShutdownHook(new Thread(hookTask, "Spark Shutdown Hook"));
}
里面先獲取FileSystem,然后再獲取FileSystem的SHUTDOWN_HOOK_PRIORITY屬性,而這個屬性在當前的FileSystem中並不存在。看起來是個版本問題,而且是org.apache.hadoop.fs.FileSystem的版本問題。
發現我的FileSystem版本在pom里面已經設置的是2.7.1,查看了下源碼,
public static final int SHUTDOWN_HOOK_PRIORITY = 10;
里面有這個屬性。
使用ide的提示,我發現我的FileSystem被兩個引用了
很明顯,hadoop-core只有到1.2.1 於是我就嘗試把hadoop-core從我的pom中移除,並且從mvn倉庫中移除。
問題解決
可以在本機運行spark讀取本地文件了
總結
說到底,這個是jar包的版本問題,最終只需要確保FileSystem的jar包是2.x以上,且沒有多個FileSystem包就可以了。
好,處理了之后就可以使用idea在本地直接運行spark的程序了。