摘要:>       4.0.0       org.chobit.scala     scala-maven-build     1.0-SNAPSHOT     jar                2.3.4         2.13.1         UTF-8                                  org.scala-lang             scala-compiler             ${scala.version}                                 junit             junit             4.12             test                                                              org.scala-lang                 scala-compiler                 ${scala.version}                                           org.scala-lang                 scala-reflect                 ${scala.version}                                           org.scala-lang                 scala-library                 ${scala.version}                                           src/main/scala         src/test/scala                                         org.scala-tools                 maven-scala-plugin                 2.15.2                                                                                            compile                             testCompile                                                                                                myApp        。--打包shell文件-->                      /shell             shell                              *.sh                            。

構建及編譯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

參考文檔

相關文章