使用maven構建scala項目
摘要:>
構建及編譯scala工程我使用過三種工具:sbt、gradle和maven。
感謝GFW,sbt的速度慢得讓人心碎。即使使用諸如廣談公服等加速方案,也還是會遇到各種各樣的問題(比如時不時的lock住)。所以pass。
gradle是最讓人驚喜的一個方案,簡潔便利上超過sbt,更遠勝maven,執行速度也沒短板。只有下載源碼這問題讓我頭疼,但也是小問題。然而,關鍵是公司發佈環境不支持gradle,所以一切休談。
最後是maven。有人說比起gradle來,maven是老人臉上的皺紋。意思是maven的配置非常繁瑣,顯得過時了。比喻非常形象。但是老人的好處就是經驗豐富,很多問題都能很快找到解決方案,雖然略嫌囉嗦但卻讓人放心。所以最終還是使用maven管理和構建生產環境中的scala項目。
介紹下如何使用maven構建scala工程。
編譯
下面是一個示例pom文件:
<?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>org.chobit.scala</groupId> <artifactId>scala-maven-build</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <spark.version>2.3.4</spark.version> <scala.version>2.13.1</scala.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-compiler</artifactId> <version>${scala.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-compiler</artifactId> <version>${scala.version}</version> </dependency> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-reflect</artifactId> <version>${scala.version}</version> </dependency> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${scala.version}</version> </dependency> </dependencies> </dependencyManagement> <build> <sourceDirectory>src/main/scala</sourceDirectory> <testSourceDirectory>src/test/scala</testSourceDirectory> <plugins> <plugin> <groupId>org.scala-tools</groupId> <artifactId>maven-scala-plugin</artifactId> <version>2.15.2</version> <executions> <execution> <goals> <goal>compile</goal> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> </plugins> <finalName>myApp</finalName> </build> </project>
scala環境最重要的三個依賴:scala-compiler、scala-reflect和scala-library都可以通過scala-compiler及其間接依賴獲取到。
一些依賴可能會間接引用不同版本的scala,所以在 < dependencyManagement > 中做了下scala版本的統一。
在 < build > 中使用了 maven-scala-plugin 插件來執行scala的編譯,不然在測試執行時會提示“ 錯誤: 找不到或無法加載主類 chobit.MyDriver ”這樣的錯誤。
打包
如果有打包需求的話建議使用assembly插件執行打包。assembly支持的打包方案非常豐富,算是同類產品裏最好的。
看個打包的示例:
首先添加assembly插件
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.2.0</version> <!--指定打包配置文件--> <configuration> <descriptors> <descriptor>src/main/assembly.xml</descriptor> </descriptors> </configuration> <!--設定在package階段執行assembly--> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
這裏的配置設置了兩個重要信息:
- 打包配置文件的具體位置:src/main/assembly.xml;
- 在package階段自動執行assembly插件;如果沒有指明,就得執行 mvn assembly : assembly 命令來進行打包。
打包配置文件的詳情:
<?xml version="1.0" encoding="UTF-8"?> <assembly> <!--這個id會出現在zip包名稱的後面,zip文件的最終名稱爲:artifactId-version-id.zip --> <id>full</id> <!--設定打包格式,支持zip、tar、tar.gz (or tgz)、tar.bz2 (or tbz2)、jar、dir、war--> <formats> <format>zip</format> </formats> <dependencySets> <!-- 用來定製工程依賴 jar 包的打包方式,依賴包的輸出路徑 --> <dependencySet> <!--依賴包存儲位置--> <outputDirectory>/libs</outputDirectory> <useProjectArtifact>false</useProjectArtifact> <includes> <!--配置要將哪些依賴的jar打到包裏--> <include>org.chobit.wp:wordpress-client</include> </includes> </dependencySet> </dependencySets> <includeBaseDirectory>true</includeBaseDirectory> <!--指設置需要包含的其他文件--> <fileSets> <!--打包jar文件--> <fileSet> <!-- 在包中的存儲位置 --> <outputDirectory>/</outputDirectory> <!-- 源文件路徑 --> <directory>target</directory> <includes> <include>*.jar</include> </includes> </fileSet> <!--打包配置文件--> <fileSet> <outputDirectory>/</outputDirectory> <directory>src/main/resources</directory> <includes> <include>*.properties</include> <include>*.conf</include> </includes> </fileSet> <!--打包shell文件--> <fileSet> <outputDirectory>/shell</outputDirectory> <directory>shell</directory> <includes> <include>*.sh</include> </includes> </fileSet> </fileSets> </assembly>
配置文件中的註釋應該已經足夠說明用法了。
這裏的代碼是從一個spark工程上copy來的,所以會有將工程打包成zip文件,又包含shell腳本這樣的內容。
在windows主機上執行 mvn clean package 命令時,可能會遇到這樣的錯誤:
[ERROR] OS=Windows and the assembly descriptor contains a *nix-specific root-relative reference (starting with slash): / [ERROR] OS=Windows and the assembly descriptor contains a *nix-specific root-relative reference (starting with slash): / [ERROR] OS=Windows and the assembly descriptor contains a *nix-specific root-relative reference (starting with slash): /shell
解決方案有兩個:
- 如果要把文件放在zip包下的根目錄,可以直接將 < outputDirectory > 標籤閉合,如: < outputDirectory / >
- 如果要把文件放在zip包下的其他目錄,可以使用相對路徑,如: < outputDirectory > . / shell < / outputDirectory >
示例代碼見: GitHub / Zhyea 。