本文仅讨论使用Maven+Scala项目打包可执行Jar从而使用spark-submit提交执行
打包的几种形式
编号 | 是否可执行 | 是否包含依赖 | 场景 |
---|---|---|---|
1 | ✖ | ✖ | 常用于制作类库或工具等,我们使用Maven引入的第三方Jar大都是此类 |
2 | ✔ | ✖ | 用于制作可执行程序,可通过Java命令启动,但是程序本身不包含依赖,多以lib目录等存放依赖,同时在主程序中标记引用关系,一般都是相对位置。主程序一般体积很小,在不改变依赖引用的情况下修改主程序可用更小的网络资源完成传输 |
3 | ✔ | ✔ | 将主程序和所有依赖类库全部打包到一个jar中,与上面的方式相比没有相对依赖库的限制,但是整体体积较大,传输不便 |
4 | ✖ | ✔ | 用于多个类库的整合封装,如多个Maven子项目合为一个类库 |
在这几种方式中,结合自身使用场景挑选合适的即可,下面我们以编写Scala程序在Spark中运行为场景来了解下 2
,3
两种打包方式的具体做法
1. Maven打包说明
Maven的组件功能通过在pom.xml
中声明配置对应的<plugin>
来实现,基本Maven目录树为
<?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>
<!--项目自身GAV-->
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>xxx</version>
<!--你依赖的类库-->
<dependencies>
<dependency>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>xxx</version>
</dependency>
</dependencies>
<!--编译/构建相关插件和配置-->
<build>
<plugins>
<plugin>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>xxx</version>
</plugin>
</plugins>
</build>
</project>
我们实现不同的打包方式都通过在<build>
节点添加插件实现
首先我们添加Scala的支持:
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<version>2.15.2</version>
<executions>
<execution>
<id>scala-compile-first</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<includes>
<include>**/*.scala</include>
</includes>
</configuration>
</execution>
<execution>
<id>scala-test-compile</id>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
2. Maven打包不包含依赖的Scala可执行Jar配置
加入主类声明插件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix><!--声明主类使用类库的相对目录名称-->
<mainClass>你的主类全路径(com.xxx.Xxx)</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
依赖类库复制插件:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!--${project.build.directory}是项目构建完成后的根目录,可执行的Jar在此目录-->
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
3. Maven打包包含依赖的Scala可执行Jar配置
添加拷贝依赖到可执行Jar的插件:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.altamob.LogicLauncher</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
4. 执行打包动作
mvn clean package -T 1C -Dmaven.test.skip=true -Dmaven.compile.fork=true
上面的命令中加入了并行编译提高打包速度,同时跳过了测试