NoClassDefFoundError for Play app with sbt 使用 Eclipse

NoClassDefFoundError for Play app with sbt using Eclipse

我正在尝试在 Scala 中编写一个 Play 2.3.8 应用程序,通过 sbt 管理它,但在 Eclipse 中编辑它。我解决了一个问题,但这似乎引入了另一个问题,并且无法解决它。

我使用 Create a new application without Activator 的确切说明设置项目(除了我还添加

scalaVersion := "2.11.6"

到 build.sbt),然后我 cd 到我的项目目录,键入 sbt,然后在 sbt 中键入 eclipse。然后我打开Eclipse,愉快的导入项目。

现在我创建了一个简单的模板 (app/views/Application/index.scala.html) 和一个调用它的控制器 (app/controllers/Application.scala)。当我进入 sbt 并输入 run 时,我可以愉快地在 localhost:9000 打开我的网络浏览器,然后出现我填充的模板。

除了一个问题(第一个),其他都很好。当我在 Eclipse 中打开 Application.scala 时,我看到一条摇摆不定的红色错误行,上面写着 "object Application is not a member of package views.html"。我使用 Nick Cooper's answer elsewhere on Stack Overflow 解决了这个问题。他说去项目 > 属性 > Java 构建路径 > 库 > 添加 Class 文件夹...然后添加 target/scala-2.11/classes_managed。这使得错误消失了。但我不想直接管理 Eclipse 的设置;我想通过 sbt 管理一切。所以通过反复试验,我发现我可以将这一行添加到我的 build.sbt 文件中...

unmanagedJars in Compile += ( baseDirectory.value / "target/scala-2.11/classes_managed" )

...现在我可以输入 sbt,然后输入 eclipse 并且 Eclipse 的配置已正确生成,没有摇摆不定的红线错误。

但这会产生第二个问题。事实证明,通过将该行引入 build.sbt 应用程序不再运行。具体来说,当我进入 sbt 时,键入 run 并打开 localhost:9000 我在我的 sbt 控制台中得到一个 NoClassDefFoundError 异常:

java.lang.NoClassDefFoundError: controllers/Application$
    at Routes$$anonfun$routes$$anonfun$applyOrElse$$anonfun$apply.apply(routes_routing.scala:51) ~[classes_managed/:na]
    at Routes$$anonfun$routes$$anonfun$applyOrElse$$anonfun$apply.apply(routes_routing.scala:51) ~[classes_managed/:na]
    at play.core.Router$HandlerInvokerFactory$$anon$$anon.call(Router.scala:217) ~[play_2.11-2.3.8.jar:2.3.8]
    at play.core.Router$Routes$TaggingInvoker.call(Router.scala:464) ~[play_2.11-2.3.8.jar:2.3.8]
    at Routes$$anonfun$routes$$anonfun$applyOrElse.apply(routes_routing.scala:51) ~[classes_managed/:na]
Caused by: java.lang.ClassNotFoundException: controllers.Application$
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_40]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_40]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_40]
    at Routes$$anonfun$routes$$anonfun$applyOrElse$$anonfun$apply.apply(routes_routing.scala:51) ~[classes_managed/:na]
    at Routes$$anonfun$routes$$anonfun$applyOrElse$$anonfun$apply.apply(routes_routing.scala:51) ~[classes_managed/:na]
[error] application - Error while rendering default error page
scala.MatchError: java.lang.NoClassDefFoundError: controllers/Application$ (of class java.lang.NoClassDefFoundError)
    at play.api.GlobalSettings$class.onError(GlobalSettings.scala:148) ~[play_2.11-2.3.8.jar:2.3.8]
    at play.api.DefaultGlobal$.onError(GlobalSettings.scala:206) [play_2.11-2.3.8.jar:2.3.8]
    at play.core.server.Server$class.logExceptionAndGetResult(Server.scala:63) [play_2.11-2.3.8.jar:2.3.8]
    at play.core.server.Server$$anonfun$getHandlerFor.apply(Server.scala:73) [play_2.11-2.3.8.jar:2.3.8]
    at play.core.server.Server$$anonfun$getHandlerFor.apply(Server.scala:71) [play_2.11-2.3.8.jar:2.3.8]

可以看到the entire (tiny) codebase on Github.

所有 class 文件似乎都在那里,并且位于完全相同的位置,无论我是否包含 "unmanagedJars" 行。这不是 Eclipse 问题,因为即使在 Eclipse 关闭时它也会发生。这似乎是一个 class 路径问题(但我不明白为什么添加到 class 路径应该隐藏一些 classes)。不管怎样,我想用 sbt 管理我的项目,并使用 Eclipse 作为编辑器。我错了什么?

我正在使用激活器,但我想它可能是一样的。

因此,Eclipse 并不真正喜欢 Play 项目或 adding/removing 库(通过 libraryDependencies 等)中的结构变化,并且到处都显示红色波浪形的东西。这就是我解决它们的方法:

activator clean compile

如果我有 added/removed 个库,我 运行

activator eclipse

以便 Eclipse 获得更改。

每次都有效。干净,干净,干净。我实际上在网上的某个地方找到了这个解决方案,但不记得在哪里,抱歉。

编辑

并在 Eclipse 中刷新项目!

经过反复试验,我找到了解决方案。不应将类路径扩展到 "target/scala-2.11/classes_managed",而应将其扩展到 "target/scala-2.11/classes"。换句话说 build.sbt 中的行应该是

unmanagedJars in Compile += ( baseDirectory.value / "target/scala-2.11/classes" )

现在我可以从 sbt 编译、测试和 运行 应用程序,并成功连接到 localhost:9000,而且我还可以在 Eclipse 中打开文件而不会看到错误行。

我仍然不知道为什么 NoClassDefFoundError 在之前的设置中真的发生了,但这是另一天的问题。