参考资料:
1.英文官方文档
2.中文官方文档,内容翻译的不全

SBT是类似maven和gradle的自动构建和包依赖管理工具,SBT是Scala技术体系下的包管理工具,都是Lightbend公司开发的,官方文档并没有介绍SBT的特点,文档中自称相对于maven和gradle有更少的概念但是如果不看文档将会遇到一些细节问题。个人的感受是,SBT类似scala技术体系的特点,就是设计思路上有一种发烧友的那种设计者自己觉得很酷但是我却感觉华而不实的那种烦躁。
本文的目的是编写一个SBT的实操项目,你不必需要非要理解SBt的原理,也能快速的使用SBT进行日常的工作。

一、安装
1.下载地址https://www.scala-sbt.org/download.html,使用最新版即可
本文使用的是windows操作环境,安装的目录是C:\opt\sbt\
2.SBT是scala开发的,所以安装SBT之前需要安装JDK
3.maven使用xml来配置,gradle使用grove脚本,SBT使用scala语言
4.安装完之后通过sbt sbtVersion查看版本信息

$ sbt sbtVersion
[warn] No sbt.version set in project/build.properties, base directory: C:\Program Files\Git
[info] Loading settings for project global-plugins from idea.sbt ...
[info] Loading global plugins from C:\Users\sesa515905\.sbt\1.0\plugins
[info] Set current project to git (in build file:/C:/Program%20Files/Git/)
[info] 1.2.

说明:sbtVersion这种参数看着就很丑,一般命令行通过-v --v --version来查看版本信息。另外,version参数好像用来看sbt当前管理的项目的版本号了

二、SBT的配置
SBT的配置一般有两个地方,一个是文件C:\opt\sbt\conf\sbtconfig.txt,另一个是~/.sbt/repositories文件(没有后缀名)

1.sbtconfig.txt

这个文件安装sbt以后就有

#这个配置文件大部分是JAVA进程启动时候的配置,保留了JAVA进程启动配置的一些命名习惯

-Dfile.encoding=UTF8
#设置SBT运行集成的的资源配置,SBT很慢增加资源可以让SBT快一些
-Xmx1024M
-XX:MaxPermSize=512m
-XX:ReservedCodeCacheSize=256m #设置SBT的代理设置,从远程仓库下载依赖包的时候使用
#说明,这个代理地址的设置只适应依赖包的下载,不适应SBT插件的下载,目前没有找到SBT插件下载的代理设置,插件你就使用手机流量下载吧
-Dhttp.proxyHost=xxx.xxx.xxx.xxx
-Dhttp.proxyPort= -Dsbt.log.format=true

2.repositories

这个文件默认是没有的,一般你需要配置私有仓库或者国内源的时候才需要使用

repositories主要配置依赖jar包的仓库服务器,特别是你有私服或者国内源的时候,对应的文件是"~/.sbt/repositories"(没有后缀名)

[repositories]
local
my: http://xxx.xxx.xxx.xxx:8081/repository/maven-public/
aliyun: http://maven.aliyun.com/nexus/content/groups/public/
typesafe: http://repo.typesafe.com/typesafe/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext], bootOnly
maven-central

三、build.sbt配置

sbt项目的根目录下会有一个build.sbt文件,用来配置包依赖和项目信息,具体内容如下

name := "my-project"
javacOptions ++= Seq("-encoding", "UTF-8") ThisBuild / organization := "com.xxxx"
ThisBuild / version := sys.props.getOrElse("PACKAGE_VERSION", "2.3")
ThisBuild / scalaVersion := "2.12.8" lazy val akkaVersion = "2.5.16"
lazy val akkaHttpVersion = "10.1.5" //依赖一个包通过%连接
libraryDependencies +="mysql" % "mysql-connector-java" % "5.1.47"
//%%表示包是依赖scala版本号的,scala下的jar包会给每个scala版本都打一个包,这是scala是特色说明scala版本兼容很差
libraryDependencies +="com.typesafe.akka" %% "akka-actor" % akkaVersion
// 当出现包依赖冲突时使用excludeDependencies排除一些依赖包,一般之后log4j有这个问题
excludeDependencies += "org.apache.logging.log4j" % "log4j-slf4j-impl"
excludeDependencies += "org.apache.logging.log4j" % "log4j-core"
excludeDependencies += "org.apache.logging.log4j" % "log4j-api"

四、多项目配置
假定你开发一个上课系统(school),这个项目结构如下
|--school
|--|--school-core
|--|--school-entity
|--|--school-business
|--|--school-service
|--|--school-server

那么你会有一个school根目录以及5个子目录,一共6个目录,这6个目录下都有一个build.sbt文件,即一共6个文件

/school/build.sbt配置

name := "school"

javacOptions ++= Seq("-encoding", "UTF-8")

ThisBuild / organization := "com.school"
ThisBuild / version := sys.props.getOrElse("PACKAGE_VERSION", "2.3")
ThisBuild / scalaVersion := "2.12.8" // root 表示跟目录
// aggregate表示根项目包括哪些子项目,这些子项目的名称要跟下面声明的变量名称一样
lazy val root = project.in(file(".")).aggregate(core,entity,business,service,server) lazy val core = project.in(file("school-core"))
//通过dependsOn(core)来管理项目依赖关系,如果依赖多个项目则格式为:dependsOn(core,xx1,xx2)
lazy val entity = project.in(file("school-entity")).dependsOn(core)
//business项目依赖了entity项目,会自动传递对core项目的依赖,不需要代码配置
lazy val business = project.in(file("school-business")).dependsOn(entity)
lazy val service = project.in(file("school-service")).dependsOn(business)
//配置mainclass的方式:mainClass in Compile := Some("com.school.server.App")
lazy val server = project.in(file("school-server")).dependsOn(service).settings(
mainClass in Compile := Some("com.school.server.App")
)

/school/school-core/build.sbt配置

name := "school-core"

lazy val akkaVersion = "2.5.16"
lazy val akkaHttpVersion = "10.1.5" //依赖一个包通过%连接
libraryDependencies +="mysql" % "mysql-connector-java" % "5.1.47"
//%%表示包是依赖scala版本号的,scala下的jar包会给每个scala版本都打一个包,这是scala是特色说明scala版本兼容很差
libraryDependencies +="com.typesafe.akka" %% "akka-actor" % akkaVersion
// 当出现包依赖冲突时使用excludeDependencies排除一些依赖包,一般之后log4j有这个问题
excludeDependencies += "org.apache.logging.log4j" % "log4j-slf4j-impl"
excludeDependencies += "org.apache.logging.log4j" % "log4j-core"
excludeDependencies += "org.apache.logging.log4j" % "log4j-api"

五、SBT常用命令

maven和gradle通过mvn build或者gradle build方式执行,sbt这样也是可以的比如sbt compile,他们的特点是是启动一个java进程,命令执行结束之后,进程自动结束
SBT官方很得意的告诉你,他还有另外的方式,就是先执行SBT命令,进入了SBT的不退出的进程中(也可以称之为SBT容器,提供了一个SBT的命令行窗口),在这个容器中再执行compile命令,这样SBT的进程就持续存在,直到你输入exit命令退出进程,所以SBT官方说就更快了,本节主要使用容器这种方式
SBT我们常用的命令有
1.exit
退出sbt进程,或者叫退出sbt容器
2.tasks
这个命令可以查看,你都有哪些命令可以使用,本节说的常用命令他都会列出来
3.projects
输入这个命令,sbt会列出sbt的所有项目,当然多项目的时候这个命令才有意义,比如本文多项目配置章节,当你输入这个命令的时候,他会把root、core、entity、business、service、server六个项目都列出来
默认root项目前面会有一个*符号,表示他是当前的默认项目,你如果想改默认项目为server,那么需要输入project server,这个时候server就成为默认项目了,再输入projects命令,那么*就跑到server项目前头了
4.compile
编译当前项目,生成*.class文件到目录:\projectName\target\scala-2.12\classes
注意要确认谁是当前项目,如果当前项目是root的话,他会把所有子项目都编译
5.clean
把compile生成的class文件都删除
6.run
运行当前项目的main class,如果项目有多个main class 他会列一个列一个所有mainClass的列表而且前头给你加1、2、3编号。你再输入编号回车,他就执行对应的mainClass,这个挺好
7.package
当前项目生成jar包到\projectName\target\scala-2.12\projectName_version.jar
说明:这个命令只生成当前项目的jar包,不会复制依赖的jar包,如果要想把依赖的包都打进来需要使用SB插件,参见SBT打包章节

sbt命令执行说明

1.执行sbt命令的时候,如果不通过容器方式实现,可以直接输入命令 sbt projects,sbt执行命令完成后sbt进程自动结束

2.多项目模式,如果再容器内,可以设置当前项目在执行命令,可以通过"projectName/run"来执行

六、SBT打包(生成JAR包且有依赖包)
背景说明
1.生产环境需要把项目打包发布到docker容器或者服务器中,打包的时候也需要添加依赖包
2.sbt package命令只生成当前项目的jar包,不能添加依赖包
3.sbt assembly是一个解决这个问题的插件(对应的命令也是assembly),他可以添加依赖包但是我没有使用。

因为他有两个问题,首先是sbt assembly版本跟scala的版本匹配的乱七八糟老是有问题;另外他老师是有jar包里.class文件的冲突,特别是日志很烦人需要手工配置build.sbt文件挨个的去解决这些冲突。
sbt assembly参考资料https://www.jianshu.com/p/460dcb709ff6
4.本文使用sbt-native-packager插件,可以解决这些问题
sbt-native-packager官方文档参见:https://www.scala-sbt.org/sbt-native-packager/

1.启用sbt-native-packager插件
参见文档:https://www.scala-sbt.org/sbt-native-packager/gettingstarted.html
1)插件引用声明
首先在项目根目录下新增"project"文件夹,在这个文件夹下新增一个"plugins.sbt"文件,即新增一个文件"\project\plugins.sbt",然后再这个文件里添加一行

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.9")

2)根项目build.sbt配置

子项目不需要做这些配置

修改根目录下的build.sbt文件,在项目设置上新增"enablePlugins(JavaAppPackaging)"调用,本文以上文的school为例来看root项目的build.sbt设置
/school/build.sbt配置

name := "school"

javacOptions ++= Seq("-encoding", "UTF-8")

ThisBuild / organization := "com.school"
ThisBuild / version := sys.props.getOrElse("PACKAGE_VERSION", "2.3")
ThisBuild / scalaVersion := "2.12.8" //enablePlugins(JavaAppPackaging)就是对项目启用了sbt-native-packager插件,每个项目都需要这么设置一下
lazy val root = project.in(file(".")).enablePlugins(JavaAppPackaging).aggregate(core,entity,business,service,server)
lazy val core = project.in(file("school-core"))
lazy val entity = project.in(file("school-entity")).dependsOn(core).enablePlugins(JavaAppPackaging)
lazy val business = project.in(file("school-business")).dependsOn(entity).enablePlugins(JavaAppPackaging)
lazy val service = project.in(file("school-service")).dependsOn(business).enablePlugins(JavaAppPackaging)
lazy val server = project.in(file("school-server")).dependsOn(service).enablePlugins(JavaAppPackaging).settings(
mainClass in Compile := Some("com.school.server.App")
)

2 stage命令行执行打包

执行打包使用stage命令,下面举例对这个命令的执行过程

sbt
project server
stage
exit

3 查看打包结果
打完的包放到这个目录下"\projectName\target\universal\stage\",在这个目录下有两个目录bin和lib,
1)lib目录下就是当前项目的jar包和所有依赖的jar包
2)bin里是stage给生成的一些shell脚本和bat脚本,用来启动打包项目,即执行"java -jar xxx.jar"命令

4.sbt-native-packager相关说明
1.通过tasks命令找不到stage命令,但是不影响使用

2.一般打包的jar里MANIFEST.MF如果添加依赖的jar包名称,那么可以直接使用"java -jar xxx.jar"命令,但是stage没有这么做,所以才大费周章使用脚本启动,具体如何修改不知道,脚本能启动也行

3.sbt-native-packager的代理不知道怎么设置,可能sbt不支持插件的设置

七、参考资料
1.maven,sbt,gradle 对classifier支持

SBT实操指南的更多相关文章

  1. Salesforce 开发 | Salesforce与微信集成实操指南

    配置前须知 Salesforce通过试点对特定客户提供Lightning WeChat Messaging,该试点需要同意特定的条款.除非Salesforce宣布WeChat Messaging全面可 ...

  2. Elasticsearch官方文档离线访问实操指南

    文章转载自:https://mp.weixin.qq.com/s/Cn9ddkj-cne5pKtfOgNPbg 延申一下,不仅能下载Elasticsearch官方文档,还能下载其他软件的官方文档,详看 ...

  3. HDFS集群PB级数据迁移方案-DistCp生产环境实操篇

    HDFS集群PB级数据迁移方案-DistCp生产环境实操篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 用了接近2个星期的时间,终于把公司的需要的大数据组建部署完毕了,当然,在部 ...

  4. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  5. 号外号外:9月13号《Speed-BI云平台案例实操--十分钟做报表》开讲了

    引言:如何快速分析纷繁复杂的数据?如何快速做出老板满意的报表?如何快速将Speed-BI云平台运用到实际场景中?         本课程将通过各行各业案例背景,将Speed-BI云平台运用到实际场景中 ...

  6. Mysql MHA(GTID)配置(实操)

    实现环境 centos6.7 MYSQL5.6.36 主:192.168.1.191 从1:192.168.1.145 从2:192.168.1.146 监测:放在从2上 192.168.1.146 ...

  7. Selenium之unittest测试框架详谈及实操

    申明:本文是基于python3.x及selenium3.x. unittest,也可以称为PyUnit,可以用来创建全面的测试套件,可以用于单元自动化测试(模块).功能自动化测试(UI)等等. 官方文 ...

  8. unittest测试框架详谈及实操(二)

    类级别的setUp()方法与tearDown()方法 在实操(一)的例子中,通过setUp()方法为每个测试方法都创建了一个Chrome实例,并且在每个测试方法执行结束后要关闭实例.是不是觉得有个多余 ...

  9. .net基础学java系列(四)Console实操

    上一篇文章 .net基础学java系列(三)徘徊反思 本章节没啥营养,请绕路! 看视频,不实操,对于上了年龄的人来说,是记不住的!我已经看了几遍IDEA的教学视频: https://edu.51cto ...

随机推荐

  1. V先生:信息流广告标题党必备的500个热词

    稍微没有全都偏,简直仅仅只永远, 已经曾经就竟然,将要立刻刚偶然, 渐渐终于决忽然,难道连续又再三, 也许必须很非常,最太十分更马上, 越极总挺常常再,屡次一定也不还. 你一定不知道.如何.最.咋.是 ...

  2. mass

    @python青岛qq群 1.爬取豆瓣,登录一次爬取后再循环就退出登录,抓不到了: 2.用requests.session试试,只要session对象不释放,就能记住登录状态的cookie: 3.se ...

  3. 05 JS基础DOM

    JS的window对象定时器: window下一些方法: <script> 弹出 window.alert('hello') 返回布尔值 var ret = window.confirm( ...

  4. 在引用阿里云库或其他库的时候,经常发生框架不兼容(原因是系统采用:Microsoft .NET Framework 4 Client Profile ),请改为Microsoft .NET Framework 4

    在引用阿里云库或其他库的时候,经常发生框架不兼容(原因是系统采用:Microsoft .NET Framework 4 Client Profile ),请改为Microsoft .NET Frame ...

  5. Caused by: java.lang.IllegalArgumentException: argument type mismatch

    下面是我的报错信息 at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java: ...

  6. MFC 中MessageBox 显示在所有窗口的最上面

    int MessageBox(   HWND hWnd,          // handle of owner window   LPCTSTR lpText,     // address of  ...

  7. query did not return a unique result: 2错误的发生

    org.springframework.dao.IncorrectResultSizeDataAccessException: query did not return a unique result ...

  8. AlphaGo的前世今生(三)AlphaGo Zero: AI Revolution and Beyond

    这是本专题的第三节,在这一节我们将以David Silver等人的Natrue论文Mastering the game of Go without human knowledge为基础讲讲AlphaG ...

  9. github 绑定域名

    github的域名其实就两种,一种是个人主页,即所谓的每个账号只有一个的个人主页,XXXX.github.io,分支是master: 另一种是项目主页,可以有无数个,网上说分支应该是gh-pages, ...

  10. WPF常用布局介绍

    概述:本文简要介绍了WPF中布局常用控件及布局相关的属性 1 Canvas Canvas是一个类似于坐标系的面板,所有的元素通过设置坐标来决定其在坐标系中的位置..具体表现为使用Left.Top.Ri ...