在不使用sbt-assembly的情况下部署具有依赖关系的scala二进制的惯用方式是什么?

时间:2019-04-18 16:47:40

标签: scala deployment dependencies

在具有依赖关系的Scala中创建有用的应用程序后,如何为它部署(创建二进制文件)?

我想知道最惯用的方式,希望这是最简单的方式。

对我来说,这通常是sbt compile,然后寻找主类:

./target/scala-2.12/classes/scala_pandoc/Main.class

然后执行它:

$ CLASSPATH="$CLASSPATH:./target/scala-2.12/classes/" scala scala_pandoc.Main --unwrap-explain
Picked up _JAVA_OPTIONS: -Xms256m -Xmx300m
java.lang.ClassNotFoundException: ujson.Value
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at scala_pandoc.Main$.main(Main.scala:51)
    at scala_pandoc.Main.main(Main.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at scala.reflect.internal.util.ScalaClassLoader.$anonfun$run$2(ScalaClassLoader.scala:106)
    at scala.reflect.internal.util.ScalaClassLoader.asContext(ScalaClassLoader.scala:41)
    at scala.reflect.internal.util.ScalaClassLoader.asContext$(ScalaClassLoader.scala:37)
    at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:132)
    at scala.reflect.internal.util.ScalaClassLoader.run(ScalaClassLoader.scala:106)
    at scala.reflect.internal.util.ScalaClassLoader.run$(ScalaClassLoader.scala:98)
    at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:132)
    at scala.tools.nsc.CommonRunner.run(ObjectRunner.scala:28)
    at scala.tools.nsc.CommonRunner.run$(ObjectRunner.scala:27)
    at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:45)
    at scala.tools.nsc.CommonRunner.runAndCatch(ObjectRunner.scala:35)
    at scala.tools.nsc.CommonRunner.runAndCatch$(ObjectRunner.scala:34)
    at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:45)
    at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:73)
    at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:92)
    at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:103)
    at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:108)
    at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

但是正如我们所看到的,它无法找到依赖项。当我编译项目时,在~/.sbt/~/.ivy2上下载/创建了一堆文件,但是都不添加这些文件(或将所有子文件夹添加到CLASSPATH)都可以解决问题。

上述过程适用于没有外部依赖性的项目。

解决方法

使用https://github.com/sbt/sbt-assembly很好(可以创建可执行文件.jar),我可以与java -jar myjar.jar一起运行,但是感觉黑/不正式/脆弱,此外,它还给我带来了更多依赖项目。


  • build.sbt

    lazy val scalatest = "org.scalatest" %% "scalatest" % "3.0.5"
    lazy val ujson = "com.lihaoyi" %% "ujson" % "0.7.1"
    
    name := "scala_pandoc"
    
    organization := "org.fmv1992"
    
    licenses += "GPLv2" -> url("https://www.gnu.org/licenses/gpl-2.0.html")
    
    lazy val commonSettings = Seq(
        version := "0.0.1-SNAPSHOT",
        scalaVersion := "2.12.8",
        pollInterval := scala.concurrent.duration.FiniteDuration(50L, "ms"),
        maxErrors := 10,
    
        // This final part makes test artifacts being only importable by the test files
        // libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % Test,
        //                                                                   ↑↑↑↑↑
        // Removed on commit 'cd9d482' to enable 'trait ScalaInitiativesTest' define
        // 'namedTest'.
        libraryDependencies ++= Seq(scalatest, ujson),
    
        scalacOptions ++= Seq("-feature", "-deprecation", "-Xfatal-warnings")
        )
    
    lazy val root = (project in file(".")).settings(commonSettings).settings(assemblyJarName in assembly := "scala_pandoc.jar")
    
  • project/build.properties

    sbt.version=1.2.8
    
  • project/plugins.sbt

    addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9")
    

相关问题:Deploy Scala binaries without dependencies

1 个答案:

答案 0 :(得分:2)

sbt程序集不是不是 hacky-它是由sbt创建者之一(Eugene Yokota)维护的,并且居住在官方sbt组织中,因此这是在sbt中部署Scala JAR的官方方式。 / p>

好吧,几种官方方式之一。您可以查看sbt-native-packager。事实是:sbt构建有很多可能的目标,以至于作者决定即使构建uberjar也不应该是一种特殊的雪花,而应该通过插件完成。

所以只需使用sbt-assembly,不要对此感到内。 是惯用的方式。