首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用scalac和sbt编译和运行jars?

用scalac和sbt编译和运行jars?
EN

Stack Overflow用户
提问于 2018-03-16 21:56:05
回答 1查看 696关注 0票数 1

我正在为我的Scala项目编译一个fat jar,根据this stackoverflow post包含我所有的依赖项,这样我就可以在Java应用程序中使用它了。我是Scala/Java/JVM的新手,所以请耐心等待。我正在使用IntelliJ和Scala2.12.4,但是我在OS终端上运行我的sbt命令。

首先,我能够运行sbt assembly并在/target/scala-2.12/中获得一个padsystem-assembly-0.0.1.jar。(我必须创建一个assembly.sbt并使用“合并策略”修改我的build.sbt以使其工作。)但是,当我尝试用scala运行这个jar时

代码语言:javascript
复制
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$1(ScalaClassLoader.scala:45)
    at scala.util.control.Exception$Catch.$anonfun$opt$1(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$1(MainGenericRunner.scala:72)
    at scala.tools.nsc.MainGenericRunner.run$1(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运行它时(这是我的主要目标):

代码语言:javascript
复制
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

现在,在您问,“您确定您的代码工作吗?”之前,我将注意到,我能够成功地sbt run我的代码,我也可以成功地sbt compilesbt package

有趣的是,如果我尝试从基本目录中sbt compile src/main/scala/OdinExtractor.scala

代码语言:javascript
复制
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 ,如果我进入src/main/scala dir并尝试运行sbt compile OdinExtractor.scala,我得到:

代码语言:javascript
复制
[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,特别是当所有的依赖项都包含在胖jar中时?

为什么当我做scalac src/main/scala/OdinExtractor.scalasbt compile OdinExtractor.scala时,我的依赖项会出现错误?我猜的第一个原因是scalac想要

scalac -cp "all:of:the:classpath:stuff:ever" OdinExtractor.scala

(顺便说一句,我不知道该怎么做.)

正如我所理解的,这就是为什么我们一开始就使用sbt,是吗?以避免乱七八糟的类路径。这就引出了我的下一个问题:当我将sbt compile指向特定的文件时,为什么它会失败?当我从src/main/scala目录运行它时,它为什么会失败呢?我不知道第一个问题,但我对第二个问题的猜测是,sbt必须始终从基本目录运行?

回到主要目标:生成一个我可以用Java运行的胖罐子..。有人知道我怎么调试这个吗?我不明白为什么程序集jar会失败,但是代码仍然与sbt run一起运行。我最初认为最好的调试方法是使用def main()编译对象,并尝试使用Scala和Java运行对象,但事实证明这非常麻烦。

最后,我有一种奇怪的感觉,也许所有这些都归结为我对classpaths的困惑,或者是我的项目结构?但既然我的东西都和sbt run在一起,我就完全不知所措了.请帮帮我!如果还有什么需要添加到我的帖子中,请告诉我,以便更清楚地说明。谢谢!

编辑-根据我的build.sbt,我确实包含了scala-library jar,以便它可以被scala-library解析。即"org.scala-lang" % "scala-library" % "2.12.4"

而且,如果它具有任何重要意义,那么我的对象有一个def main而不是extends App。不确定这是否重要..。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-18 19:30:24

最终答案是build.sbt的。我在this stackoverflow post中找到了答案。我不得不补充

代码语言:javascript
复制
mainClass in assembly := Some("NameOfMyMainClass")

进入build.sbt

在那之后,我做了

sbt clean assembly

并且能够同时运行java -jar target/.../my-fat-jar.jarscala target/.../my-fat-jar.jar

大声喊出@大笑--因为他指出我应该使用java -jar,并回答我关于sbt compile src/...的问题:')

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49330054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档