【问题标题】:App running under SBT doesn't find a class from Classpath jar在 SBT 下运行的应用程序找不到 Classpath jar 中的类
【发布时间】:2016-02-01 10:00:02
【问题描述】:

我有一个使用 sbt 的 Scala 项目。它在 Eclipse 下运行得非常好,但是,尝试在 sbt 下运行它(sbt 'run mount 1440' — 包括我需要的参数)会导致 ClassNotFoundException — 它找不到 jnr.ffi.provider.jffi.NativeClosureProxy 类。但是,运行sbt 'last run' 显示jnr-ffi-2.0.3.jar 文件(包括所述类)实际上包含在类路径中。对正在发生的事情有什么建议吗?

github 上的可用资源:https://github.com/FileJunkie/vkfs

【问题讨论】:

  • 您应该在此处包含您的代码的相关位,以便对将来可能遇到类似问题的其他访问者有用

标签: scala sbt jnr


【解决方案1】:

您的构建 sbt 无效。

首先libraryDependecys 之间需要有空行。

lazy val root = (project in file(".")).
  settings(
    name := "vkfs",
    version := "1.0",
    scalaVersion := "2.11.7"
  )

libraryDependencies += "org.scalaj" %% "scalaj-http" % "1.1.6"

libraryDependencies += "org.json4s" %% "json4s-jackson" % "3.2.11"

libraryDependencies += "com.github.serceman" % "jnr-fuse" % "0.1"

第二,无法解析依赖“com.github.serceman”。这意味着要么

总而言之,Eclipse 似乎会自动执行某些操作,因此您的程序会运行。当涉及到您的 build.sbt 时,它无效(缺少空行)并且无法正确解决依赖关系。 我想知道,你怎么能通过sbt 'run mount 1440' 开始呢。

在更正空行并运行 sbt 'run mount 1440' 我得到

Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256M; support was removed in 8.0
[info] Set current project to vkfs (in build file:/home/.../IdeaProjects/vkfs/)
[info] Updating {file:/home/.../IdeaProjects/vkfs/}root...
[info] Resolving com.github.serceman#jnr-fuse;0.1 ...
[warn]  module not found: com.github.serceman#jnr-fuse;0.1
[warn] ==== local: tried
[warn]   /home/.../.ivy2/local/com.github.serceman/jnr-fuse/0.1/ivys/ivy.xml
[warn] ==== public: tried
[warn]   http://repo1.maven.org/maven2/com/github/serceman/jnr-fuse/0.1/jnr-fuse-0.1.pom
[info] Resolving jline#jline;2.12.1 ...
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: com.github.serceman#jnr-fuse;0.1: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
sbt.ResolveException: unresolved dependency: com.github.serceman#jnr-fuse;0.1: not found
at sbt.IvyActions$.sbt$IvyActions$$resolve(IvyActions.scala:213)
at sbt.IvyActions$$anonfun$update$1.apply(IvyActions.scala:122)
at sbt.IvyActions$$anonfun$update$1.apply(IvyActions.scala:121)
[ ... truncated ... ]

编辑(关于来自 jcenter 的依赖)

将以下行添加到您的 build.sbt(记住额外的空行)

resolvers += Resolver.jcenterRepo

将 jcenter 添加到您的解析器列表中。

编辑 2

Resolver.jcenterRepo 在 SBT 0.13.5 中不可用,因此

resolvers += "jcenter" at "https://jcenter.bintray.com/"

是必需的。

编译成功后并运行相关错误是

java.lang.RuntimeException: java.lang.NoClassDefFoundError: jnr/ffi/provider/jffi/NativeClosureProxy
at jnr.ffi.provider.jffi.NativeClosureProxy.newProxyFactory(NativeClosureProxy.java:220)

最终结果

v 0.1 中的库“com.github.serceman”似乎存在问题,因为它无法通过反射正确实例化某些类。

解决方案

通过将fork in run := true 添加到build.sbt 解决了问题。

【讨论】:

  • 感谢您注意到libraryDependencies 行之间缺少空行,但它没有任何改变。至于jnr-fuse,它可以从 jcenter 存储库中获得(在您发布的手册中,据说这个 repo 是默认可用的),并且我的 sbt 在我清理缓存后成功解决了这个依赖关系。我提到的ClassNotFoundException 只能在运行时访问,因此由于 jnr-fuse 在您的机器上无法解析,因此您无法到达我遇到此异常的那一点。
  • 不,不是真的。默认情况下不添加 repo jcenter。相反,它是文档状态Resolver.jcenterRepo 的预定义变量。将编辑我的帖子...
  • 嗯。我想知道为什么我的 sbt 完全解决了这种依赖关系。但是,将resolvers += Resolver.jcenterRepo 添加到build.sbt 对我来说没有任何改变。
  • 你是如何开始 sbt 的?只需从 bash/shell 通过 sbt 启动 sbt,然后在交互式 sbt 控制台中调用 run mount 1440
  • 运行 sbt 'run mount 1440' 并使用您描述的方式会导致相同的结果 - 没有依赖性问题,所有必要的文件都在类路径中(使用 last run 命令检查),包括 jnr-ffi-2.0.3.jar,而这个包含在 sbt 下找不到的类的确切文件。
猜你喜欢
  • 2018-10-20
  • 2016-01-18
  • 2021-12-27
  • 2015-06-08
  • 2018-06-11
  • 2014-06-29
  • 2020-05-21
  • 2013-06-30
相关资源
最近更新 更多