使用IntelliJ构建的工件中的“NoClassDefFoundError”

时间:2017-12-12 08:59:18

标签: scala intellij-idea jar jvm sbt

我使用Intellij Idea 2017.3(终极版)从Scala / SBT项目构建工件(可执行的Jar); Scala版本是2.12。 由于我最近向Scallop添加了一个依赖项,因此我不能再执行Jar文件,因为Scallop类ScallopConf不在Jar文件中:

$ java -jar executable.jar 
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/rogach/scallop/ScallopConf
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    [...]
Caused by: java.lang.ClassNotFoundException: org.rogach.scallop.ScallopConf
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 19 more

我可以通过手动检查来确认ScallopConf类没有打包到Jar文件中。所有其他依赖关系都在那里,无论它们是最初添加还是稍后添加。

这是我将依赖项添加到项目根目录中的build.sbt文件的方式:

libraryDependencies += "org.rogach" %% "scallop" % "3.1.1"

项目在IDE和sbt compile内编译都很好。我也可以在IDE中运行它。

我以标准方式在IDE中创建了工件。有什么特别需要注意的,可能与扇贝有关吗?

2 个答案:

答案 0 :(得分:0)

正如@Andrey所指出的,当SBT依赖关系发生变化时,工件设置不会自动更新。为确保所有内容都是最新的,因此解决方法是在更新SBT依赖项后重新创建工件。

因此,此问题与特定依赖关系无关(本例中为Scallop)。

答案 1 :(得分:0)

jar的类文件之间发生冲突,因此在上面的示例中,当从 File |中删除库时。 项目结构 | 工件 | 输出布局。一切运行正常。

就我而言,我也依赖于其他jar,因此当我执行删除所有其他库的活动时。 ClassNotFoundException消失了,但是NoClassFoundEx即将针对我删除的依赖库而来。

为了获得准确的解决方案,我被迫一个接一个地评估所有jar文件,并删除了不需要的库以获取精确的解决方案。