利用Gradle如何构建scala多模块工程的步骤详解

前言

Scala是一门强大的语言,受到很多人的喜爱,我也曾经尝试学习过。不过Scala官网专用的构建工具SBT就不那么好用了。我曾经想将SBT的软件包保存路径设置到D盘,还想设置网络代理,不过最后都没搞明白怎么回事。相信也有很多同学想学习Scala,但是却被SBT挡在了门外。偶然之下我发现现在Gradle增加了scala插件,可以完美支持Scala项目。

前段时间终于无法忍受sbt慢如龟速的编译打包速度了。稍稍调研了一下,就果断切换到了gradle。由于调研得比较匆忙,在使用过程中遇到了各种问题。好在最后都能解决了。

我这里使用scala主要是用来编写spark job。由于我自己的一些需要,这些job中有几个是多模块的。在这里简单解释一下如何使用gradle构建scala多模块项目。

这里用我最近开发的项目来做说明。项目名称是consumer-portrait-job,有两个子模块:common和compute。

步骤如下

首先在项目根目录下创建一个settings.gradle文件,这个文件主要用来描述项目名称及子模块信息:

rootProject.name = 'consumer-portrait-job'
include 'common', 'compute'

然后再创建一个build.gradle文件。这个文件描述了主项目及子项目的一些通用配置。配置如下:

allprojects {
 apply plugin: 'idea'
 group = 'com.zhyea.portrait'
 version = '0.1-SNAPSHOT'
}

subprojects {
 apply plugin: 'scala'
 sourceCompatibility = 1.7
 targetCompatibility = 1.7
 ext {
  scalaVersion = '2.10.5'
  sparkVersion = '1.4.1'
 }

 repositories {
  mavenLocal()
  maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
  mavenCentral()
 }

 dependencies {
  testCompile group: 'junit', name: 'junit', version: '4.12'
  compileOnly group: 'org.apache.spark', name: 'spark-core_2.10', version: sparkVersion
  compileOnly group: 'org.scala-lang', name: 'scala-compiler', version: scalaVersion
 }

 task mkdirs() {
  sourceSets*.scala.srcDirs*.each { it.mkdirs() }
  sourceSets*.resources.srcDirs*.each { it.mkdirs() }
 }
}

在这个配置文件中包含两个大的模块:allprojects和subprojects。

allprojects中的配置是所有项目共享的(包含根项目)。在这里,我定义了项目的groupId和version等信息,并应用了gradle的idea插件。

subprojects的配置是所有子项目通用的。

在subprojects中的第一行声明了使用gradle的scala插件。

接下来的配置项“sourceCompatibility”声明了编译时使用的jdk版本;“targetCompatibility”确保了编译生成的class与指定版本的jdk兼容。

在ext中声明了子项目中可以使用的一些变量。我这里是声明了scala和spark的版本。

repositories项配置了当前项目可以使用的仓库。这里使用的第一个仓库是本机的maven库,第二库是ali提供的repository服务,第三个库是maven中央库。(曾经研究过如何让gradle和maven公用同一个本地仓库,不过最后也是不了了之)。

dependencies中声明了所有子模块都需要使用的依赖项。这里用到了scala库和spark库,这两个库只会在编译期用到,所以声明使用的依赖类型是compileOnly(这种依赖类型是gradle Java插件独有的,gradle scala插件继承自java插件,所以也可以使用)。

task mkdirs是一个自定义任务。在根项目配置完settings.gradle和build.gradle后,执行“gradle mkdirs”命令完成子模块目录的创建工作。

在两个子模块common和compute下创建build.gradle文件并做配置。

common模块的build.gradle配置详情:

project(':common') {
  dependencies {
    compile group: 'com.typesafe', name: 'config', version: '1.3.2'
  }
}

这里只是声明了一下commons模块独有的依赖项。

compute模块是启动模块,在该模块中有spark任务的驱动类。该模块的build.gradle配置详情:

project(':compute') {
  dependencies {
    compile project(":common")
    compileOnly group: 'org.apache.spark', name: 'spark-sql_2.10', version: sparkVersion
    compile group: 'net.liftweb', name: 'lift-json_2.10', version: '2.6.3'
  }

  jar {
    archiveName = 'consumer-portrait.jar'
  }

  task zip(type: Zip) {
    into('lib') {
      from(configurations.runtime) {
include '*typesafe*', '*common*', '*bitmap-core*', '*RoaringBitmap*'
      }
    }
    into('') {
      from jar
      from 'doc'
    }
  }
}

配置中的第一行dependencies仍然是配置compute模块的依赖项。其中略需注意的是对common模块的依赖。

接下来的jar声明指明了将该模块打成的jar包的名称。脚本中需要根据包名来调用模块生成的包,默认生成的包名会带上版本信息,不太合适。

最后是一个自定义任务。该任务的目标是将一些必要的jar和其他文件打成一个zip包,以便于上传任务到执行服务器。任务中的第一个部分是将一些运行时依赖打入zip包中的lib目录,使用include关键字提示包含运行时依赖中指定名称的包,也可以使用exclude关键字排除一些包。第二部分是将生成的jar和本地doc目录中的文件打入zip包的根目录。

就这样。有空再写个示例项目留着参考。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Scala基础简介及代码示例

    一.主要内容 Scala中变量的声明与函数定义 Scala中的控制结构 Scala中的数据类型 1:变量声明与函数定义 变量声明:val 和 var ,两者的区别是val声明的变量是不可变的,而var声明的变量可变 带返回值 scala> def max(x:Int,y:Int):Int = { | if(x>y) x | else y | } max: (x: Int, y: Int)Int scala> max(1,2) res5: Int = 2 不带返回值 scala> d

  • Scala安装及环境图文配置教程

    Window 上安装配置Scala,供大家参考,具体内容如下 1.Java(JDK)环境配置,详见 Java(JDK)环境 2.从 Scala 官网下载安装包:下载地址 3.双击开始一步一步的安装: 4.同意 License: 5.此处可以选择取消"Update system PATH"的设置,随后手动设置环境变量: 6.开始安装吧: 7.安装完成: 8.接着需要设置系统环境变量: 右击[我的电脑]--[属性]--[高级系统设置]--[环境变量],如下图: 在用户变量下新增 SCALA

  • Windows7下安装Scala 2.9.2教程

    1. 下载Scala 2.9.2 由于最新的Scala 2.10稳定版还没完成,所以最好是下载最新的Scala稳定版:2.9.2版. 下载地址:http://www.scala-lang.org/downloads/distrib/files/scala-2.9.2.msi 下载msi版本的好处在于,环境变量自动配置,否则你需要手动设置两个环境变量. SCALA_HOME环境变量,指向Scala的安装目录. PATH环境变量,要包含 %SCALA_HOME%\bin的值. 2. 安装Scala

  • 深入理解Scala函数式编程过程

    深入理解Scala函数式编程过程 我们马上开始一段变态的过程 如果要求立方和,可以这么做 35 * 35 * 35 68 * 68 * 68 没毛病,抽象一点儿,写个函数: def cube(n: Int) = n * n * n cube(35) cube(68) 省事儿了,如果求1到10的立方和,OK,写个递归 def cube(n: Int) = n * n * n def sumCube(a: Int, b: Int): Int = if (a > b) 0 else cube(a) +

  • 利用Gradle如何构建scala多模块工程的步骤详解

    前言 Scala是一门强大的语言,受到很多人的喜爱,我也曾经尝试学习过.不过Scala官网专用的构建工具SBT就不那么好用了.我曾经想将SBT的软件包保存路径设置到D盘,还想设置网络代理,不过最后都没搞明白怎么回事.相信也有很多同学想学习Scala,但是却被SBT挡在了门外.偶然之下我发现现在Gradle增加了scala插件,可以完美支持Scala项目. 前段时间终于无法忍受sbt慢如龟速的编译打包速度了.稍稍调研了一下,就果断切换到了gradle.由于调研得比较匆忙,在使用过程中遇到了各种问题

  • ios 使用xcode11 新建项目工程的步骤详解

    xcode11新建项目工程,新增了scenedelegate这个类,转而将原Appdelegate负责的对UI生命周期的处理担子接了过来.故此可以理解为:ios 13以后,Appdelegate负责处理App生命周期,scenedelegate负责处理UI生命周期的处理. 1.使用scenedelegate(iOS 13以下黑屏) 如果创建app支持的最低版本是ios13,可以考虑直接使用. 举例使用系统底部栏: - (void)scene:(UIScene *)scene willConnec

  • 利用nginx + node在阿里云部署https的步骤详解

    缘起 最近在写node+mongodb版本的灵犀微商城,所以免不了要自己去部署自己的https证书到阿里服务器,下面将实现的过程完整的给大家总结下,话不多说了,来一起看看详细的介绍吧. HTTPS和HTTP的区别主要如下: 1.https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用. 2.http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议. 3.http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443. 4.ht

  • Gradle环境下导出Swagger为PDF的步骤详解

    说明 我个人是一直使用Swagger作为接口文档的说明的.但是由于在一些情况下,接口文档说明需要以文件的形式交付出去,如果再重新写一份文档难免有些麻烦.于是在网上看到了Swagger2Markup + asciidoctor导出PDF的方法,百度一番后感觉网上的文章还是有很多没有描述清楚的地方,遂还是硬着头皮把官方的英文文档大致浏览了一下,按照自己的思路整理出具体的步骤. 本文用到的工具: Gradle - 4.10.3 SpringBoot - 2.1.6.RELEASE Swagger -

  • 使用Vite+Vue3+Vant全家桶快速构建项目步骤详解

    目录 引言 一.vue3全家桶模板介绍 1.版本依赖 2.全家桶内置集成 二.安装 tive-cli 命令行工具 三.生成项目 四.项目体验 引言 随着Vue3 和 Vite 版本的不断更新完善,开发体验有了质的飞跃.因此,越来越多的大厂也逐步拥抱 Vue3. 利用Vite 脚手架工具可以很轻松生成以 Vue3 为模板的项目,但是作为Vue全家桶的 vue-router.vuex.axios等成员,需要自己一个一个去配置.于是便自行开发了本文讲到的 tive-cli 脚手架模板工具,只需短短几个

  • python模块之re正则表达式详解

    一.简单介绍 正则表达式是一种小型的.高度专业化的编程语言,并不是python中特有的,是许多编程语言中基础而又重要的一部分.在python中,主要通过re模块来实现. 正则表达式模式被编译成一系列的字节码,然后由用c编写的匹配引擎执行.那么正则表达式通常有哪些使用场景呢? 比如为想要匹配的相应字符串集指定规则: 该字符串集可以是包含e-mail地址.Internet地址.电话号码,或是根据需求自定义的一些字符串集: 当然也可以去判断一个字符串集是否符合我们定义的匹配规则: 找到字符串中匹配该规

  • 利用FlubuCore用C#来写DevOps脚本的方法详解

    前言 随着近些年微服务的流行,有越来越多的开发者和团队所采纳和使用,它的确提供了很多的优势也解决了很多的问题,但是我们也知道也并不是银弹,提供优势的同时它也给我们的开发人员和团队也带来了很多的挑战. 为了迎接或者采用这些新技术,开发团队需要更加注重一些流程或工具的使用,这样才能更好的适应这些新技术所带来的一些问题. 对于流程行问题,敏捷的Scrum能够很好的提升产品开发团队之间的协作问题,那么对于应用变的越来越复杂这种情况,它最直接的问题就是带来了开发运维的复杂性,这个时候我们就需要使用工具来解

  • Python写脚本常用模块OS基础用法详解

    收集了一些关于OS库的用法,整理归纳一下,方便使用 import os # 系统操作 print(os.sep) # 获取当前系统的路径分隔符 print(os.name) # 获取当前使用的工作平台 print(os.getenv('PATH')) # 获取名为 PATH 的环境变量 print(os.getcwd()) # 获取当前的路径 print(os.environ['PATH']) # 可以返回环境相关的信息 不传参时,以字典的方式返回所有环境变量 # 调用系统命令 os.syste

  • node gyp安装canvas原生模块编译node pregyp详解

    目录 关于node-gyp node-pre-gyp canvas安装过程追踪 1. 安装canvas 2. canvas的package的命令脚本 3. node-pre-gyp install命令 4. 下载预构建的二进制文件 让node-pre-gyp通过淘宝源下载预构建文件 关于node-gyp node-gyp是一个用 Node.js 编写的跨平台命令行工具,用于为 Node.js 编译本机插件模块.它包含之前由 Chromium 团队使用的 gyp-next项目的供应副本,扩展以支持

  • python中模块的__all__属性详解

    python模块中的__all__属性,可用于模块导入时限制,如: from module import * 此时被导入模块若定义了__all__属性,则只有__all__内指定的属性.方法.类可被导入. 若没定义,则导入模块内的所有公有属性,方法和类 # kk.py class A(): def __init__(self,name,age): self.name=name self.age=age class B(): def __init__(self,name,id): self.nam

随机推荐