使用 scalac 与 sbt 编译和 运行 罐子?
compiling and running jars with scalac vs sbt?
我正在尝试为我的 Scala 项目编译一个 fat jar,其中包含根据 this Whosebug post 的所有依赖项,以便我可以在 Java 应用程序中使用它。我是Scala/Java/JVM的新手,所以请耐心等待。我正在使用 IntelliJ 和 scala 2.12.4,但是我正在从 OS X 终端 运行ning 我的 sbt
命令。
首先,我能够 运行 sbt assembly
并在 /target/scala-2.12/
中获得 padsystem-assembly-0.0.1.jar
。 (我必须制作一个 assembly.sbt
并用 "Merge Strategy" 修改我的 build.sbt
才能让它工作。)但是当我尝试 运行 这个 jar 与 scala
computer: dir user$ scala target/scala-2.12/padsystem-assembly-0.0.1.jar
scala target/scala-2.12/padsystem-assembly-0.0.1.jar
java.lang.NullPointerException
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at scala.reflect.internal.util.ScalaClassLoader.$anonfun$tryClass(ScalaClassLoader.scala:45)
at scala.util.control.Exception$Catch.$anonfun$opt(Exception.scala:242)
at scala.util.control.Exception$Catch.apply(Exception.scala:224)
at scala.util.control.Exception$Catch.opt(Exception.scala:242)
at scala.reflect.internal.util.ScalaClassLoader.tryClass(ScalaClassLoader.scala:45)
at scala.reflect.internal.util.ScalaClassLoader.tryToInitializeClass(ScalaClassLoader.scala:41)
at scala.reflect.internal.util.ScalaClassLoader.tryToInitializeClass$(ScalaClassLoader.scala:41)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.tryToInitializeClass(ScalaClassLoader.scala:125)
at scala.reflect.internal.util.ScalaClassLoader.run(ScalaClassLoader.scala:92)
at scala.reflect.internal.util.ScalaClassLoader.run$(ScalaClassLoader.scala:91)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:125)
at scala.tools.nsc.CommonRunner.run(ObjectRunner.scala:22)
at scala.tools.nsc.CommonRunner.run$(ObjectRunner.scala:21)
at scala.tools.nsc.JarRunner$.run(MainGenericRunner.scala:14)
at scala.tools.nsc.CommonRunner.runAndCatch(ObjectRunner.scala:29)
at scala.tools.nsc.CommonRunner.runAndCatch$(ObjectRunner.scala:28)
at scala.tools.nsc.JarRunner$.runAndCatch(MainGenericRunner.scala:14)
at scala.tools.nsc.JarRunner$.runJar(MainGenericRunner.scala:26)
at scala.tools.nsc.MainGenericRunner.runTarget(MainGenericRunner.scala:72)
at scala.tools.nsc.MainGenericRunner.run(MainGenericRunner.scala:85)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:101)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
当我尝试 运行 它时 java (这是我的主要目标):
computer: dir user$ java target/scala-2.12/padsystem-assembly-0.0.1.jar
Error: Could not find or load main class target.scala-2.12.padsystem-assembly-0.0.1.jar
现在,在你提问之前,"Are you sure your code is working?",我会注意到我能够 sbt run
我的代码成功,我也可以 sbt compile
和 sbt package
它也成功了。
有趣的是,如果我尝试从基本目录sbt compile src/main/scala/OdinExtractor.scala
:
sbt compile src/main/scala/OdinExtractor.scala
[info] Loading settings from idea.sbt ...
[info] Loading global plugins from /Users/user/.sbt/1.0/plugins
[info] Loading project definition from /Users/user/PAD_IE/project/project
[info] Loading settings from assembly.sbt,plugins.sbt ...
[info] Loading project definition from /Users/user/PAD_IE/project
[info] Loading settings from build.sbt ...
[info] Set current project to padsystem (in build file:/Users/user/PAD_IE/)
[info] Executing in batch mode. For better performance use sbt's shell
[success] Total time: 4 s, completed Mar 16, 2018 3:35:49 PM
[error] Expected ID character
[error] Not a valid command: src (similar: set)
[error] Expected project ID
[error] Expected configuration
[error] Expected ':' (if selecting a configuration)
[error] Expected key
[error] Not a valid key: src (similar: sources, ps, run)
[error] src/main/scala/OdinExtractor.scala
[error] ^
或者如果我尝试 scalac src/main/scala/OdinExtractor.scala
或 如果我 cd
进入 src/main/scala
目录并尝试 运行 sbt compile OdinExtractor.scala
我得到:
[info] Loading settings from idea.sbt ...
[info] Loading global plugins from /Users/user/.sbt/1.0/plugins
[info] Updating ProjectRef(uri("file:/Users/user/.sbt/1.0/plugins/"), "global-plugins")...
[info] Done updating.
[info] Set current project to scala (in build file:/Users/user/PAD_IE/src/main/scala/)
[info] Executing in batch mode. For better performance use sbt's shell
[info] Compiling 1 Scala source to /Users/user/PAD_IE/src/main/scala/target/scala-2.12/classes ...
[error] /Users/user/PAD_IE/src/main/scala/OdinExtractor.scala:3:12: object clulab is not a member of package org
[error] import org.clulab.odin.Mention
[error] ^
[error] /Users/user/PAD_IE/src/main/scala/OdinExtractor.scala:4:12: object clulab is not a member of package org
[error] import org.clulab.processors.Document
[error] ^
[error] /Users/user/PAD_IE/src/main/scala/OdinExtractor.scala:5:12: object vinci is not a member of package org
[error] import org.vinci.pad.padsystem.PadSystem
[error] ^
[error] three errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 1 s, completed Mar 16, 2018 3:38:06 PM
为什么我能够 sbt run
我的代码成功,但不能 运行 使用 scala 或 java 的 jar,尤其是当所有依赖项都包含在肥罐?
为什么在执行 scalac src/main/scala/OdinExtractor.scala
和 sbt compile OdinExtractor.scala
时我的依赖项会出现错误?我猜第一个是因为 scalac
想要
scalac -cp "all:of:the:classpath:stuff:ever" OdinExtractor.scala
.
(顺便说一下,我不知道该怎么做...)
据我了解,这就是我们使用 sbt
开头的原因,是吗?为了避免混乱的类路径的东西。这让我想到了下一个问题:当我将 sbt compile
指向特定文件时,为什么它会失败?为什么当我从 src/main/scala
目录 运行 时它会失败?我不知道第一个问题,但我对第二个问题的猜测是 sbt
必须 always 是基本目录中的 运行?
回到主要目标:生成一个我可以 运行 和 Java 的 fat jar...有谁知道我该如何调试它?我不明白为什么程序集 jar 失败,但代码仍然 运行s 和 sbt run
。我最初认为调试它的最佳方法是仅使用 def main()
编译对象,然后尝试使用 Scala 和 Java 对其进行 运行,但事实证明这非常麻烦。
最后,我有一种奇怪的感觉,也许所有这一切都归结为 1) 我对 classpaths
的困惑,或者 2) 也许是我的项目结构?但是由于我的东西 运行 与 sbt run
相关,我完全不知所措......请帮忙!让我知道是否还有其他需要添加到我的 post 中以使其更清楚的内容。谢谢!
编辑 -
根据我的 build.sbt
,我确实包含了 scala-library
jar,因此它可以被 Java 解析。
IE。 "org.scala-lang" % "scala-library" % "2.12.4"
此外,如果它有任何重要性,我的对象有一个 def main
而不是 extends App
。不确定这是否重要...
答案最终是build.sbt
。我在 中找到了答案。我必须添加
mainClass in assembly := Some("NameOfMyMainClass")
进入build.sbt
.
之后,我做了
sbt clean assembly
并且能够 运行 java -jar target/.../my-fat-jar.jar
和 scala target/.../my-fat-jar.jar
。
感谢@laughedelic 指出我应该使用 java -jar
,并回答我关于 sbt compile src/...
的问题 :')
我正在尝试为我的 Scala 项目编译一个 fat jar,其中包含根据 this Whosebug post 的所有依赖项,以便我可以在 Java 应用程序中使用它。我是Scala/Java/JVM的新手,所以请耐心等待。我正在使用 IntelliJ 和 scala 2.12.4,但是我正在从 OS X 终端 运行ning 我的 sbt
命令。
首先,我能够 运行 sbt assembly
并在 /target/scala-2.12/
中获得 padsystem-assembly-0.0.1.jar
。 (我必须制作一个 assembly.sbt
并用 "Merge Strategy" 修改我的 build.sbt
才能让它工作。)但是当我尝试 运行 这个 jar 与 scala
computer: dir user$ scala target/scala-2.12/padsystem-assembly-0.0.1.jar
scala target/scala-2.12/padsystem-assembly-0.0.1.jar
java.lang.NullPointerException
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at scala.reflect.internal.util.ScalaClassLoader.$anonfun$tryClass(ScalaClassLoader.scala:45)
at scala.util.control.Exception$Catch.$anonfun$opt(Exception.scala:242)
at scala.util.control.Exception$Catch.apply(Exception.scala:224)
at scala.util.control.Exception$Catch.opt(Exception.scala:242)
at scala.reflect.internal.util.ScalaClassLoader.tryClass(ScalaClassLoader.scala:45)
at scala.reflect.internal.util.ScalaClassLoader.tryToInitializeClass(ScalaClassLoader.scala:41)
at scala.reflect.internal.util.ScalaClassLoader.tryToInitializeClass$(ScalaClassLoader.scala:41)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.tryToInitializeClass(ScalaClassLoader.scala:125)
at scala.reflect.internal.util.ScalaClassLoader.run(ScalaClassLoader.scala:92)
at scala.reflect.internal.util.ScalaClassLoader.run$(ScalaClassLoader.scala:91)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:125)
at scala.tools.nsc.CommonRunner.run(ObjectRunner.scala:22)
at scala.tools.nsc.CommonRunner.run$(ObjectRunner.scala:21)
at scala.tools.nsc.JarRunner$.run(MainGenericRunner.scala:14)
at scala.tools.nsc.CommonRunner.runAndCatch(ObjectRunner.scala:29)
at scala.tools.nsc.CommonRunner.runAndCatch$(ObjectRunner.scala:28)
at scala.tools.nsc.JarRunner$.runAndCatch(MainGenericRunner.scala:14)
at scala.tools.nsc.JarRunner$.runJar(MainGenericRunner.scala:26)
at scala.tools.nsc.MainGenericRunner.runTarget(MainGenericRunner.scala:72)
at scala.tools.nsc.MainGenericRunner.run(MainGenericRunner.scala:85)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:101)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
当我尝试 运行 它时 java (这是我的主要目标):
computer: dir user$ java target/scala-2.12/padsystem-assembly-0.0.1.jar
Error: Could not find or load main class target.scala-2.12.padsystem-assembly-0.0.1.jar
现在,在你提问之前,"Are you sure your code is working?",我会注意到我能够 sbt run
我的代码成功,我也可以 sbt compile
和 sbt package
它也成功了。
有趣的是,如果我尝试从基本目录sbt compile src/main/scala/OdinExtractor.scala
:
sbt compile src/main/scala/OdinExtractor.scala
[info] Loading settings from idea.sbt ...
[info] Loading global plugins from /Users/user/.sbt/1.0/plugins
[info] Loading project definition from /Users/user/PAD_IE/project/project
[info] Loading settings from assembly.sbt,plugins.sbt ...
[info] Loading project definition from /Users/user/PAD_IE/project
[info] Loading settings from build.sbt ...
[info] Set current project to padsystem (in build file:/Users/user/PAD_IE/)
[info] Executing in batch mode. For better performance use sbt's shell
[success] Total time: 4 s, completed Mar 16, 2018 3:35:49 PM
[error] Expected ID character
[error] Not a valid command: src (similar: set)
[error] Expected project ID
[error] Expected configuration
[error] Expected ':' (if selecting a configuration)
[error] Expected key
[error] Not a valid key: src (similar: sources, ps, run)
[error] src/main/scala/OdinExtractor.scala
[error] ^
或者如果我尝试 scalac src/main/scala/OdinExtractor.scala
或 如果我 cd
进入 src/main/scala
目录并尝试 运行 sbt compile OdinExtractor.scala
我得到:
[info] Loading settings from idea.sbt ...
[info] Loading global plugins from /Users/user/.sbt/1.0/plugins
[info] Updating ProjectRef(uri("file:/Users/user/.sbt/1.0/plugins/"), "global-plugins")...
[info] Done updating.
[info] Set current project to scala (in build file:/Users/user/PAD_IE/src/main/scala/)
[info] Executing in batch mode. For better performance use sbt's shell
[info] Compiling 1 Scala source to /Users/user/PAD_IE/src/main/scala/target/scala-2.12/classes ...
[error] /Users/user/PAD_IE/src/main/scala/OdinExtractor.scala:3:12: object clulab is not a member of package org
[error] import org.clulab.odin.Mention
[error] ^
[error] /Users/user/PAD_IE/src/main/scala/OdinExtractor.scala:4:12: object clulab is not a member of package org
[error] import org.clulab.processors.Document
[error] ^
[error] /Users/user/PAD_IE/src/main/scala/OdinExtractor.scala:5:12: object vinci is not a member of package org
[error] import org.vinci.pad.padsystem.PadSystem
[error] ^
[error] three errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 1 s, completed Mar 16, 2018 3:38:06 PM
为什么我能够 sbt run
我的代码成功,但不能 运行 使用 scala 或 java 的 jar,尤其是当所有依赖项都包含在肥罐?
为什么在执行 scalac src/main/scala/OdinExtractor.scala
和 sbt compile OdinExtractor.scala
时我的依赖项会出现错误?我猜第一个是因为 scalac
想要
scalac -cp "all:of:the:classpath:stuff:ever" OdinExtractor.scala
.
(顺便说一下,我不知道该怎么做...)
据我了解,这就是我们使用 sbt
开头的原因,是吗?为了避免混乱的类路径的东西。这让我想到了下一个问题:当我将 sbt compile
指向特定文件时,为什么它会失败?为什么当我从 src/main/scala
目录 运行 时它会失败?我不知道第一个问题,但我对第二个问题的猜测是 sbt
必须 always 是基本目录中的 运行?
回到主要目标:生成一个我可以 运行 和 Java 的 fat jar...有谁知道我该如何调试它?我不明白为什么程序集 jar 失败,但代码仍然 运行s 和 sbt run
。我最初认为调试它的最佳方法是仅使用 def main()
编译对象,然后尝试使用 Scala 和 Java 对其进行 运行,但事实证明这非常麻烦。
最后,我有一种奇怪的感觉,也许所有这一切都归结为 1) 我对 classpaths
的困惑,或者 2) 也许是我的项目结构?但是由于我的东西 运行 与 sbt run
相关,我完全不知所措......请帮忙!让我知道是否还有其他需要添加到我的 post 中以使其更清楚的内容。谢谢!
编辑 -
根据我的 build.sbt
,我确实包含了 scala-library
jar,因此它可以被 Java 解析。
IE。 "org.scala-lang" % "scala-library" % "2.12.4"
此外,如果它有任何重要性,我的对象有一个 def main
而不是 extends App
。不确定这是否重要...
答案最终是build.sbt
。我在
mainClass in assembly := Some("NameOfMyMainClass")
进入build.sbt
.
之后,我做了
sbt clean assembly
并且能够 运行 java -jar target/.../my-fat-jar.jar
和 scala target/.../my-fat-jar.jar
。
感谢@laughedelic 指出我应该使用 java -jar
,并回答我关于 sbt compile src/...
的问题 :')