使用Eclipse的sbt Play应用程序的NoClassDefFoundError

时间:2015-03-18 20:04:19

标签: eclipse scala playframework sbt classpath

我正在尝试在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上打开我的Web浏览器,然后会出现我的填充模板。

除了一个问题(第一个问题)之外,一切都很好。当我在Eclipse中打开Application.scala时,我得到一条摇摆不定的红色错误行,上面写着“对象应用程序不是包view.html的成员”。我用Nick Cooper's answer elsewhere on Stack Overflow解决了这个问题。他说要去Project>属性> Java构建路径>图书馆>添加类文件夹...然后添加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$1$$anonfun$applyOrElse$1$$anonfun$apply$1.apply(routes_routing.scala:51) ~[classes_managed/:na]
    at Routes$$anonfun$routes$1$$anonfun$applyOrElse$1$$anonfun$apply$1.apply(routes_routing.scala:51) ~[classes_managed/:na]
    at play.core.Router$HandlerInvokerFactory$$anon$13$$anon$14.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$1$$anonfun$applyOrElse$1.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$1$$anonfun$applyOrElse$1$$anonfun$apply$1.apply(routes_routing.scala:51) ~[classes_managed/:na]
    at Routes$$anonfun$routes$1$$anonfun$applyOrElse$1$$anonfun$apply$1.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$1(Server.scala:63) [play_2.11-2.3.8.jar:2.3.8]
    at play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:73) [play_2.11-2.3.8.jar:2.3.8]
    at play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:71) [play_2.11-2.3.8.jar:2.3.8]

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

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

2 个答案:

答案 0 :(得分:1)

我通过进一步的试验和错误找到了解决方案。不应将类路径扩展到"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在之前的设置中确实发生了,但这又是另一天的问题。

答案 1 :(得分:0)

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

因此,Eclipse并不真正喜欢Play项目中的结构更改或添加/删除库(通过libraryDependencies等)并且在任何地方都显示出红色的波浪形状。这就是我解决它们的方法:

activator clean compile

如果我添加/删除了库,我运行

activator eclipse

以便Eclipse获得更改。

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

修改

在Eclipse中刷新项目!