在不使用sbt-assembly的情况下,使用依赖项部署scala二进制文件的惯用方法是什么?

问题描述 投票:0回答:1

在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运行,但感觉hackish /非官方/脆弱,此外,它还对我的项目更多的依赖。


  • build.sbtlazy 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.propertiessbt.version=1.2.8
  • project/plugins.sbtaddSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9")

相关问题:Deploy Scala binaries without dependencies

scala deployment dependencies
1个回答
2
投票

sbt-assembly并不是hacky - 它由sbt创建者之一(Eugene Yokota)维护并且生活在官方sbt组织中,因此它是在sbt中部署Scala JAR的官方方式。

嗯,几种官方方式之一。你可以看看sbt-native-packager。问题在于:有很多可能的sbt构建目标,作者认为即使构建一个uberjar也不应该是一个特殊的雪花,它应该通过一个插件完成。

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

© www.soinside.com 2019 - 2024. All rights reserved.