在做spark項目時,我們常常面臨如何在本地將其打包,上傳至裝有spark服務器上運行的問題。下面是我在項目中嘗試的兩種方案,也踩了不少坑,兩者相比,方案一比較簡單,本博客提供的jar包適用於spark版本2.0以下的,如果jar包和版本不對應會出現找不到類或方法等錯誤提示信息,它主要借助於eclipse和現成的jar包進行打包應用,只能從官網上下載對應的jar包,局限很大。方案二是借助於IntelliJ + maven方式,它只要配置好pom.xml文件,在文件中寫明自己的運行環境即可,通用(推薦),另外IntelliJ軟件炒雞好用,建議大家不要由於自己習慣哪款軟件就先入為主。
1.准備工作
scala:在本機上裝scala,下載鏈接 https://www.scala-lang.org/download/ ,如果是在windows下,請下載 msi 版本。

jdk:下載鏈接 https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
如果是需要在本地打包后上傳至裝有spark的服務器上運行,則務必保證本地和服務器上版本保持一致,否則會導致找不到類或方法等錯誤。
2. 方案一:eclipse打jar包(適用於spark2.0以下)
(1)安裝 eclipse和配置完java環境后,在工具欄 Help -> Install New Software,輸入scala ,通過鏈接下載運行scala代碼的插件。
(2)下載插件后,新建一個scala工程,測試Spark程序,統計單詞個數。

(3)在工程下新建目錄 lib,將兩個jar包(hadoop-0.20.2-CDH3B4-core.jar,spark-assembly-1.6.3-SNAPSHOT-hadoop2.5.0-cdh5.3.2.jar)拷貝到 lib 下,選中這兩個jar包右擊 Build Path,加到Referenced Libraries中。
jar包下載鏈接:https://pan.baidu.com/s/1dQjJR8vtl01wp6JLEgRp3w 密碼:20hh
(4)選中工程,右擊,選中Export,選擇JAR 文件->Next,只選擇src文件,填寫保存位置和名字。


(5)把jar包傳到安裝有spark的服務器目錄下,寫好submit腳本(如下圖所示),這里我新建了Jar目錄,把jar包放到該目錄下,后面緊接着是傳遞給函數的一個參數(文件路徑),執行該腳本。

(6)如果出現 找不到類等錯誤,一般就是版本出現了問題。我在eclipse中加載了hadoop和assmbly的jar包后也提示了該錯誤,當時沒選擇對scala的版本,可通過如下方式改變其版本,選中 scala library container后右擊 properties,選擇2.10.6版本。當然,你需要這些版本和服務器上裝有的spark、scala、hadoop版本一致才可以。這種方式需要從網上找版本一致的jar包,體驗很差,不推薦。

2. 方案二:IntelliJ + maven(推薦)
(1)安裝IntelliJ
下載鏈接 https://www.jetbrains.com/idea/download/#section=windows,選用右邊的Community版本就ok。
(2)安裝IntelliJ中的scala插件
如果在主界面可通過 File -> Settings -> Plugins -> Browse respositories 的方式安裝scala插件,具體如下圖所示。由於這里我已經安裝完畢,所以沒有顯示 Install 按鈕。如果剛裝完 IntelliJ,進入初始界面,可選擇右下方的Configure -> Plugins 來安裝scala插件。



(3)新建maven項目
最新的IntelliJ中一般都會安裝有maven,這里通過 File -> New -> Project -> Maven 新建maven項目,在配置maven頁面需選中復選框,選擇scala-archetype-simple:1.2 ,點擊next,填寫信息自己隨意起名字就好,無礙。在配置maven環境這塊需要勾選兩個復選框,再選擇合適的maven路徑和setting files路徑,一般是在安裝IntelliJ目錄下的plugins中可以找到。具體如下圖所示:





(4)配置maven項目的pom.xml文件
注意:當你配置完xml信息后,右下角這里會提示import changes,點擊它,等待頁面最下面Running信息加載完就可以到下一步了。否則不能及時同步xml中的配置,會導致打包失敗(親測)。配置文件信息如下,方便大家自行粘貼。我這里配置的spark版本是 2.1.1, scala版本 2.11,hadoop 版本 2.7.3,這里需要和服務器上版本一致,如果不知道服務器上spark信息,可以輸入命令行 spark-shell 查看。hadoop可通過 hadoop version 查看。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test</groupId> <artifactId>Test</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spark.version>2.1.1</spark.version> <scala.version>2.11</scala.version> <hadoop.version>2.7.3</hadoop.version> </properties> <dependencies> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_${scala.version}</artifactId> <version>${spark.version}</version> </dependency> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_${scala.version}</artifactId> <version>${spark.version}</version> </dependency> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-hive_${scala.version}</artifactId> <version>${spark.version}</version> </dependency> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-streaming_${scala.version}</artifactId> <version>${spark.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-streaming-kafka_${scala.version}</artifactId> <version>${spark.version}</version> </dependency> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-mllib_${scala.version}</artifactId> <version>${spark.version}</version> </dependency> </dependencies> <build> <sourceDirectory>src/main/scala</sourceDirectory> <testSourceDirectory>src/test/scala</testSourceDirectory> </build> </project>

![]()
(5)在test目錄下右鍵選擇scala script新建scala類,如果沒有scala script,則新建一個空白文件,名字和文件中的類名需一致,這里隨意起個名字WordCount,用 .scala 作為后綴名。然后會提示沒有Scala SDK,按照提示點擊Setup Scala SDK安裝即可。scala文件內容如下。


package com.test
import org.apache.spark.{SparkContext, SparkConf}
object WordCount {
def main(args: Array[String]) {
/**
* SparkContext 的初始化需要一個SparkConf對象
* SparkConf包含了Spark集群的配置的各種參數
*/
val conf = new SparkConf().setAppName("testRdd")//設置本程序名稱
//.setMaster("local") 設置單線程模式
//Spark程序的編寫都是從SparkContext開始的
val sc = new SparkContext(conf)
val data = sc.textFile("hdfs:///user/aisearch/user/zhengkaiyu001/graph_scala/conf/entity_params")//讀取本地文件
data.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).collect().foreach(println)//循環打印
}
}
這里注意下目錄結構,com和test是上下級目錄,這樣在下面打包過程中會出現些問題,同時我會說下是怎么解決的。
(6)開始打包
- File -> Project Structure -> Artifacts -> + -> JRE -> From modules with dependencies -> ok ,具體信息如下圖所示。
- 在通過Search by Name選擇主類的時候,會自動提供出項目中是主類的可選項,但是如果上一步驟中的目錄結構是上下級時,就沒有自動提示信息,打包會失敗。那該如何解決呢?原因其實沒有根據 pom.xml 配置文件及時更新,所以打開配置文件可以選擇刪除一行,右下方出現 import changes 后點擊,等待加載完畢后再把那行粘貼上(也可以調出maven project (file->setting->appearance->show tool windows bar)->clean 后,再選中項目右擊->maven->Reimport)。這樣目錄就變為com.test。再重復打包過程就會有自動提示主類的信息,選擇主類后點擊ok。
- 在進行打包設置時,只留下'Test' compile output 和Test.jar包,將其他jar包都刪除,output directory是jar包的輸出路徑。
- Build:這里注意是 Build Artifacts,選擇build 或者 rebuild,其實rebuild的作用是當你變動了代碼,可直接rebuild重新打包,無須重新配置打包環境。
- 打包過程中會提示錯誤信息,把多余的文件test目錄下的和main目錄下的App刪除即可。
,







(7)運行
把輸出的jar包上傳至裝有spark的服務器,這里我是新建了個目錄,把jar包傳到Jars目錄下,運行命令見如下所示的腳本文件:

注意踩坑:
- 當配置pom.xml后一定要import changes(在打包過程中才會默認有選擇的主類),如果應用沒有及時import changes,你可以調出maven project (file->setting->appearance->show tool windows bar)->clean 后,再選中項目右擊->maven->Reimport

- pom.xml文件中的版本號需要和服務器上的各版本一一對應
參考博客:
https://blog.csdn.net/xingyx1990/article/details/80752041
