业界一直把sbt simple build tools ,叫成 SB tool,说实话,入门没有maven 和gradle 简单, 稍微不留意就不知道哪里就报错了。
不用sbt 的高阶功能还凑合着用,一旦你想用点,折磨的你死去活来的。
比如 sbt 的plugins,
我就发现 scala sbt 好像跨版本兼容 简直就是狗屎一般,scala 和sbt 的版本最后是用一致的,否则 报错 何时了。
另外 sbt 的plugin 插件 也要用对 版本号的,否则 调试何时了。
另外 sbt 的版本分两个分支 一个 1.0.X 一个 0.13.X,之前一直使用
0.13.13咩有问题,但是发现在 plugin 安装上 0.13.13 和0.13.15都伤透了我的心,我scala 用的是 2.12.1,我发现 sbt 0.13.13 和0.13.15所依赖的scala版本都是 2.10,就差不多 是jdk6吧。最后在sbt 官网选择了,sbt 1.0.4,这个版本算是sbt的 正房了 当时最新版本。
也是用这个版本 真正解决了 sbt-assembly这个难题,用其他版本所出现的问题是,assembly 依赖找不到 ,assembly 命令识别不了,asembly 的关键字无法识别。
参考文件 :https://github.com/sbt/sbt-assembly#using-published-plugin
https://github.com/softprops/assembly-sbt
https://github.com/sbt/sbt-assembly/tree/0.11.2
http://wiki.jikexueyuan.com/project/sbt-getting-started/using-plugin.html
http://www.scala-sbt.org/download.html
下面步入正题
1.首先是目录结构 ,一定不要放错位置了。
用IDEA 创建 sbt scala 项目后,需要额外 再创建两个 文件
./project/plugins.sbt 和 assembly.sbt
其中plugins.sbt在 项目 根目录下的project目录下
assembly.sbt则在 项目的根目录下,放错位置,则assembly就不可以好好运行了
然后是文件内容
我的环境是
scala 2.12.1
sbt 1.0.4
java 8
IDEA 2017.2 + 因为他的 scala 插件2017.2.5才开始支持sbt 1.0.x !!!!
使用低版本的IDEA 一直有bug的
在 plugins.sbt中
logLevel := Level.Warn addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6")
在 ./project/build.properties 中
sbt.version = 1.0.4
在 assembly.sbt
resolvers += Resolver.url("bintray-sbt-plugins", url("http://dl.bintray.com/sbt/sbt-plugin-releases"))(Resolver.ivyStylePatterns)
在 build.sbt
name := "DebugHDP"
version := "1.0"
scalaVersion := "2.12.1"
scalaVersion in ThisBuild := "2.12.1"
lazy val commonSettings = Seq(
organization := "com.example",
version := "0.1.0-SNAPSHOT"
)
lazy val app = (project in file(".")).
settings(commonSettings: _*).
settings(
name := "fat-jar-test"
).enablePlugins()
resolvers in Global ++= Seq(
"Sbt plugins" at "https://dl.bintray.com/sbt/sbt-plugin-releases",
"Maven Central Server" at "http://repo1.maven.org/maven2",
"TypeSafe Repository Releases" at "http://repo.typesafe.com/typesafe/releases/",
"TypeSafe Repository Snapshots" at "http://repo.typesafe.com/typesafe/snapshots/"
)
然后在 项目根目录下
输入 sbt update
稍等片刻,sbt首次使用记得 要翻墙 ,或者使用中国仓库镜像
这个时候 assembly 插件一般就会安装成功了
然后 输入 sbt plugins 可查看 本项目中的依赖的插件
`
[info] Loading settings from plugins.sbt ...
[info] Loading project definition from /Users/linkedmemuller/Documents/gitlab/DebugHDP/project
[info] Loading settings from assembly.sbt,build.sbt ...
[info] Set current project to DebugHDP (in build file:/Users/linkedmemuller/Documents/gitlab/DebugHDP/)
In file:/Users/linkedmemuller/Documents/gitlab/DebugHDP/
sbt.plugins.IvyPlugin: enabled in app
sbt.plugins.JvmPlugin: enabled in app
sbt.plugins.CorePlugin: enabled in app
sbt.plugins.JUnitXmlReportPlugin: enabled in app
sbt.plugins.Giter8TemplatePlugin: enabled in app
sbtassembly.AssemblyPlugin: enabled in app
`
我们发现 sbtassembly.AssemblyPlugin: enabled in app
说明assembly插件安装成功了,之后输入
sbt assembly 就可以打 fat jar了
正常的sbt打包是不会把依赖的第三方jar包打到里面的。
然后我们找到 打好的jar 包的路径
在terminal 中 使用
java -jar jarName
然后就可以正常使用了。
另外 sbt 创建的scala 项目是没有resources目录的,需要自己手工创建 ,这也有一个重点就是 resources目录的位置 和maven的不一样
sbt 的Resources 要放在 项目根目录下 ./src/,千万不要放到了./src/main,否则是无法加载到目录下的配置文件的。
最后的是 项目结构是 ./src/resources
我们可以通过 在 ./src/resources 目录下创建 properties属性文件 检验
import java.io.FileInputStream
import java.util.Properties
/**
* Created by linkedmemuller on 13/12/2017.
*/
class DeHdfs {
}
object DeHdfs{
def main(args: Array[String]): Unit = {
println("hello world clean")
val fileProperties:Properties=new Properties()
val filepath=DeHdfs.getClass.getClassLoader.getResource("./file.properties").getPath
println(filepath)
fileProperties.load(new FileInputStream(filepath))
val name=fileProperties.getProperty("Zoo")
println(name+"name")
}
}
这个时候还有一点要注意的就是 需要把 ./src/resources 目录 标记为 资源目录 ,
File --> project Structure --> Modules --> 然后找到 ./src/resources
选中 右键点击 选择第三个 Resources就可以了,然后打包时,才可以把 Resource的配置文件打包的jar包中
|
2
When you package it the csv-file will reside in the jar archive; right? Then you can't access it directly as a file. Instead you need to ask for a stream:
val stream = getClass.getResourceAsStream("/data.csv")
Possibly you need to wrap the stream in a InputStreamReader for the CSVReader to accept it:
val reader = new InputStreamReader(stream)
CSVReader.open(reader)
@Absurd-Mind you are completely right, it is CSVReader.open(reader). I've corrected the question now. I got it working with @thoredge's approach. But as he said,
I had to wrap the stream in an InputStreamReader as follows:
val reader = new InputStreamReader(getClass.getResourceAsStream("/data.csv"))
and then I used that reader with the CSV reader CSVReader.open(reader)
总的来说 要用流Stream 读取,
getClass.getClassLoader.getResourceAsStream(path)
用普通的getResource 就会失败
在 build.sbt 加入这些
unmanagedSourceDirectories in Test := Seq(baseDirectory.value / "test")
unmanagedResourceDirectories in Compile := Seq(baseDirectory.value / "src/main/resources")
,另外我们也可以选择 直接用IDEA自带的打包工具
File --> project Structure --> Artifacts 创建 新的 包,然后选择 主类。在idea 的菜单栏就选择 Build --- Build Artifacts --build 就可以了
What is estimate to support SBT 1.0.x? or java.lang.ClassNotFoundException: org.jetbrains.sbt.CreateTasks$
最新版 IDEA 下载地址
https://www.jetbrains.com/idea/download/#section=mac
https://www.jetbrains.com/idea/download/previous.html?fromIDE=
sbt发布assembly解决jar包冲突问题 deduplicate: different file contents found in the following
http://blog.csdn.net/oopsoom/article/details/41318599
https://stackoverflow.com/questions/25144484/sbt-assembly-deduplication-found-error