I am trying to write a Play 2.3.8 application in Scala, managing it via sbt but editing it in Eclipse. I worked round one problem, but this seems to introduce another, and cannot work out how to solve it.
I set up the project using the exact instructions to Create a new application without Activator (except I also add
scalaVersion := "2.11.6"
to build.sbt), then I cd to my project directory, type sbt and once in sbt I type eclipse. Then I open Eclipse and happily import the project.
Now I create a simple template (app/views/Application/index.scala.html) and a controller which calls it (app/controllers/Application.scala). When I go into sbt and type run I can happily open my web browser at localhost:9000 and my populated template appears.
All is good apart from one problem (the first one). When I open up Application.scala in Eclipse I get a wiggly red error line saying "object Application is not a member of package views.html". I solved that using Nick Cooper's answer elsewhere on Stack Overflow. He said to go to Project > Properties > Java Build Path > Libraries > Add Class Folder... and then add target/scala-2.11/classes_managed. That makes the error go away. But I don't want to manage Eclipse's settings directly; I want to manage everything via sbt. So by trial and error I found that I can add this line to my build.sbt file...
unmanagedJars in Compile += ( baseDirectory.value / "target/scala-2.11/classes_managed" )
...and now I can type sbt followed by eclipse and Eclipse's config is generated correctly, with no wiggly red line errors.
But this creates a second problem. It turns out that by introducing that line into build.sbt the application no longer runs. Specifically when I go into sbt, type run and open localhost:9000 I get a NoClassDefFoundError exception in my sbt console:
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]
You can see the entire (tiny) codebase on Github.
All the class files seem to be all there, and in exactly the same locations, regardless of whether or not I include the "unmanagedJars" line. It's not an Eclipse problem because it happens even when Eclipse is closed. It seems to be a classpath issue (but I can't understand why adding to a classpath should hide some classes). Regardless of that, I'd like to manage my project with sbt and use Eclipse just as the editor. What am I getting wrong?
I have found a solution through further trial and error. Instead of extending the classpath to "target/scala-2.11/classes_managed" it should be extended to "target/scala-2.11/classes". In other words the line in build.sbt should be
unmanagedJars in Compile += ( baseDirectory.value / "target/scala-2.11/classes" )
Now from sbt I can compile, test and run the application, and connect successfully to localhost:9000, and I can also open the files in Eclipse without seeing error lines.
I still don't know why the NoClassDefFoundError really occurred in the previous setup, but that's a problem for another day.
I am using activator but I guess it might be the same.
So, Eclipse does not really like structural changes in a Play project or adding/removing libraries (via libraryDependencies, etc) and displays red squiggly things everywhere. This is how I solve them:
activator clean compile
If I have added/removed libraries, I run
activator eclipse
so that Eclipse gets the changes.
It works everytime. Clean, clean, clean. I actually found this solution somewhere on the Net a while a go but cannot remember where, sorry.
EDIT
And refresh the project in Eclipse!
Related
I am currently building a Play Framework application in Scala that requires the use of the Gephi Java library.
I tried adding Gephi as a managed dependency in SBT, but SBT cannot resolve all of Gephi's dependencies. This is a known issue. I then simply tried to add the whole Gephi JAR in my lib/ folder as an unmanaged dependency. IntelliJ detects the library just fine and I can compile my application perfectly fine. The problem is an exception occurs immediately upon starting the application, and it seems to be related to dependency injection:
play.api.UnexpectedException: Unexpected exception[NoSuchMethodError: com.google.common.base.Objects.firstNonNull(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;]
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:174)
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:126)
at scala.Option.map(Option.scala:146)
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:126)
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:124)
at scala.util.Success.flatMap(Try.scala:231)
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:124)
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:116)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
Caused by: java.lang.NoSuchMethodError: com.google.common.base.Objects.firstNonNull(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
at com.google.common.cache.CacheBuilder.getKeyStrength(CacheBuilder.java:529)
at com.google.common.cache.LocalCache.<init>(LocalCache.java:242)
at com.google.common.cache.LocalCache$LocalManualCache.<init>(LocalCache.java:4718)
at com.google.common.cache.CacheBuilder.build(CacheBuilder.java:807)
at com.google.inject.internal.WeakKeySet.<init>(WeakKeySet.java:55)
at com.google.inject.internal.InheritingState.<init>(InheritingState.java:67)
at com.google.inject.internal.InjectorShell$Builder.getState(InjectorShell.java:209)
at com.google.inject.internal.InjectorShell$Builder.lock(InjectorShell.java:115)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:103)
at com.google.inject.Guice.createInjector(Guice.java:96)
I tried removing all mention of Gephi in the code, while still having the JAR sitting in my lib/ folder, but it results in the same exception.
Gephi is really important for this project, so I can't just move on to another library. Any ideas?
Remove that jar fom lib, add those two additional resolvers (in build.sbt)
resolvers += "NetBeans" at "http://bits.netbeans.org/nexus/content/groups/netbeans/"
resolvers += "gephi" at "https://raw.github.com/gephi/gephi/mvn-thirdparty-repo/"
and run activator update
I am trying to set up IntelliJ for my Scala development after hearing how much better it is compared to alternatives. But I can't seem to run anything. The problems I'm facing are as follows:
As soon as the project is created, the console shows SBT failures
My build.sbt file shows red wiggles (compile time errors)
The confusing part is that opening the "SBT Console" view from within the IDE works fine.
The error trace is something along the lines of:
[info] Loading project definition from D:\workspaces\intellij\scala\untitled\project
java.io.IOException: The filename, directory name or volume label syntax is incorrect
[error] (*:update) java.io.IOException: The filename, directory name or volume label syntax is incorrect
Would anyone please know what can cause this? I have tried deleting the project and creating a new one but the problem still persists.
UPDATE
Just had a look at .sbt\boot\update.log and something seems fishy. Is it just me or the sbt.ivy.home is completely borked?
impossible to define new type: class not found: org.apache.ivy.osgi.obr.OBRResolver in [] nor Ivy classloader
impossible to define glob matcher: org.apache.ivy.plugins.matcher.GlobPatternMatcher was not found.
setting 'jline.esc.timeout' to '0'
setting 'sbt.ivy.home' to 'D:\software\installed\sbt\.ivy2 -Divy.home=D:\software\installed\sbt\.ivy2'
setting 'java.runtime.name' to 'Java(TM) SE Runtime Environment'
I have finally managed to hunt down the root cause. The errors were due to rogue environment variables set in my profile related to SBT (specifically SBT_OPTS). Once I deleted all of them and started with a clean slate, things started working on expected.
In a given project that is driven by sbt there is some kind of corruption in the project libraries specifically for a MavenLocal repository used for kafka-spark-9.7.2.jar in which:
references to the classes provided by that jar are marked as "symbol not found" by the editor parser
however the editor (strangely) does offer to import the classes
but after accepting the import, the symbols are still marked in red as unresolved.
The following attempts to "clean things up" have already been performed:
Build | Make Project
Build | Rebuild Project
In addition I have verified that the project does build from
sbt package
on the command line
UPDATE After re-running sbt gen-idea the librraries are still not found by the Parser. yet the libraries exist -even IJ knows about them as shown in the following screenshot. Why is it that IJ can find the library
C:\Users\S80035683\.ivy2\cache\org.apache.kafka\kafka\jars\kafka-0.7.2-spark.jar!\kafka\api\FetchRequest.class
However IJ is unable to resolve any classes from that library in the Parser?
You have to build the project for Intellij, try to do this in your project root:
sbt idea with-sources=yes
This should build the project structure from scratch and add the right dependencies, usually I refresh the project after adding a dependency or a jar.
Edit:
To use the command you need this plugin, otherwise you can use gen-idea but I used it only a few times and I'm not sure how it will work out.
Edit2:
There was some confusion, first, for the IDEA SBT console you don't need to prepend the sbt command since you already are inside sbt:
If you have the sbt plugin for idea you can use gen-idea with-source=yes (without prepending sbt)
From the terminal, either you go to your project root and type sbt to enter the sbt console and use gen-idea or idea with-sources=yes (without prepending sbt)
or directly sbt gen-idea or if you have the plugin sbt idea with-sources=yes (prepending sbt)
To reach the sbt console inside idea you need to install the sbt plugin on preferences -> plugin and search for sbt and then View -> Tool Windows -> SBT Console:
To start the console click on the play button, to kill the console on the skull.
I had the same problem. I fixed it by directly writing the CLASSES and SOURCES of the problematic library. This can be found in .idea/libraries/SBT__<problematic library>_jar.xml
I am trying to use IntelliJ with a play framework 2.11 application.
I installed the Play Framework 2 plugin and the Scala plugin for IntelliJ.
I created a Play application. I have been struggling writing and running Specs 2 tests in IntelliJ. My run config says to run "make" first when running the Specs 2 test, however it doesn't look like my test classes are being generated. Keeps on telling me that it could not find the specification. When I look on the file system, there is no code in target/test-classes, the directory is empty. Further, it seems to take a LONG time to do the build, at least compared to running the Play console.
I wanted to see how people are using Play with IntelliJ. Do you just use IntelliJ as an editor, and run everything through the Play console?
Is there a way whereby you can run your Application tests in IntelliJ (getting your test classes to run)?
I have never had any problem running the Play console and running ~test-only test=xxx.Spec. It has typically been rather fast.
Here is the exception I am getting in IntelliJ when I try to run my Specs2 tests:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.jetbrains.plugins.scala.testingSupport.specs2.JavaSpecs2Runner.runSingleTest(JavaSpecs2Runner.java:130)
at org.jetbrains.plugins.scala.testingSupport.specs2.JavaSpecs2Runner.main(JavaSpecs2Runner.java:76)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.RuntimeException: can not create specification: test.ApplicationSpec
at scala.sys.package$.error(package.scala:27)
at org.specs2.specification.SpecificationStructure$.createSpecification(BaseSpecification.scala:96)
at org.specs2.runner.ClassRunner.createSpecification(ClassRunner.scala:64)
at org.specs2.runner.ClassRunner.start(ClassRunner.scala:35)
at org.specs2.runner.ClassRunner.main(ClassRunner.scala:28)
at org.specs2.runner.NotifierRunner.main(NotifierRunner.scala:24)
... 11 more
Update: In newer versions if IntelliJ IDEA, it is no longer necessary to create the module from play/activator. IntelliJ IDEA has now a really good support for SBT projects. If exists, delete all the idea related directories inside your project. Then in IntelliJ IDEA click File -> Open and choose your build.sbt file. That's all.
IntelliJ IDEA has a good integration for the Play Framework 2. Sometimes it jams, but most of the time it runs. I use it to run(single, all) tests, start or debug the play application and edit my code (o; And this all from within the IDE and without the sbt console.
Here is a short tutorial with the most important steps. Currently I use IntelliJ IDEA 12.1 with the newest Play Framework 2 and Scala plugins.
1. Create a new application
play new myapp
2. Create the IDE module
Start the play console:
cd newapp
play
Create the module:
idea with-sources=yes
exit
3. Configure the IDE
Open the newly created project
Open the module settings(select project and press F4)
Add the Scala library to your project
Select Modules->myapp->Dependencies
Press the plus Icon and select Library(2)
Add the Scala 2.10.0 Project Library
Select the Compiler Library in the Scala Facet
Select Facets->Scala(myapp)
Set the Compiler library to Scala 2.10.0
Fix the errors
Select Modules->myapp-build->Dependencies->scala-2.9.2 and press the minus icon
Select Libraries->Scala 2.9.2 and press the minus icon
Fix the output Path for the myapp-build module
Select Modules->myapp-build->Paths
Append classes to the Output path(X:\projects\myapp\project\target\scala_2.9.2\classes)
Append test-classes to the Test output path(X:\projects\myapp\project\target\scala_2.9.2\test-classes)
4. Run a test
Select the ApplicationSpec under the test directory and click Run 'ApplicationSpec' from the context menu. You should get an error that the compiled template could not be found. This is because the IDE doesn't compile the templates, but this can be done by run the application once. Also follow point 5 and then run the test again.
5. Run the application
Select a controller and click Run Play 2 App from context menu. This should start the application on address: http://localhost:9000/.
6. Update dependencies
If you update your application dependencies then you must tell the IDE about this changes. Also after running the play update command you must close the IDE and remove some files from project directory. If you execute the play idea command before removing the files, you get double dependencies in your play project.
Execute the following steps to update your dependencies:
Run the update task from your play console
Remove the .idea_modules and .idea/libraries directories
Run the idea with-sources=yes command in the play console
Run step 3 again
Play console includes a fork of a sbt plugin named sbt-idea. The play's fork got a little lagged behind the original plugin, and has some problems in IntelliJ when you run play idea. You can use the original plugin, which doesn't have any issues. In order to use this plugin in your play project, you need to..
1.Add the following lines to project/plugins.sbt file: (the blank line in the middle is required)
resolvers += "Sonatype snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/"
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.5.1")
2.Run gen-idea from the play console.
I usually used IntellijIDEA (version 12.0.4) only for Play Framework code editor because of:
Auto saving feature by default
Rather fast IntelliSense feature
Dracula UI, it is an eye-pleasure for me
And I usually run and debug the apps with Play SBT console. It's reasonable fast. But, sometimes when executing play command on console, I found that the loading-project-info task take too long time (nearly 10 minutes). I don't know why this sometimes happen, but overall the use of Play SBT console is my choice.
I'm doing that because there is usually should-not-be-the-problem-things intepreted as error like following :
The first time when I start learning Play Framework, I was facing such problem. So, at the end, I choose to use Play SBT console to run and debugging app then.
And sorry I cannot answer for the question number 2. Until now I only tried running and debugging play application. For testing purpose I've never tried before for Play 2.x.
I successfully implemented and ran several Scala tutorials in Eclipse using the Scala plugin. Then suddenly I tried to compile and run an example, and this error came up:
Exception in thread "main" java.lang.NoClassDefFoundError: hello/HelloWorld
Caused by: java.lang.ClassNotFoundException: hello.HelloWorld
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:315)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:330)
at java.lang.ClassLoader.loadClass(ClassLoader.java:250)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:398)
After this point I could no longer run any Scala programs in Eclipse. I tried cleaning and rebuilding my project, closing and reopening my project, and closing and reopening Eclipse.
Eclipse version number 3.5.2 and Scala plugin 2.8.0
Here is the original code:
package hello
object HelloWorld {
def main(args: Array[String]){
println("hello world")
}
}
If you see this when you attempt to run as a Scala application then the most likely explanation is that your project didn't compile and no class files were generated. Please check whether or not that's the case: look in your project's output folder for hello/HelloWorld.class.
If your project didn't compile that could either be because there's an error which you've missed (and if this error isn't being reported in the Problems view that could be a bug, in which case please open a ticket on Trac) or because you've turned off automatic builds and not done a manual build of your project.
I had the same problem. Project doesn't compile but there are no errors highlighted and AFAIK the code is OK. It seems to be a problem with the Run Configurations.
Solution 1: Delete the existing Run Configuration for your object and create a new one
Solution 2: Create a new object and cut / paste all your code into that file
When running "clean" does not un-hose Eclipse, I next try saving my work, exiting Eclipse, and re-starting. That usually gets things going again, but not always. A few times I've had to update the Scala plugin with a more recent version (I'm using the latest nightly), to get things working again. I doubt that this worked because the new plugin happened to fix the bug, but rather expect that loading the new plugin gives the whole Eclipse-Scala
system a "total reset" that gets it unhosed.
I was getting this problem in a project that combined .java & .scala files.
The solution for me was:
Remove all .java files
Edit the scala code as needed so it compiles without them.
Add the .java files back in.
Edit the scala code back.
The other solutions given here didn't work for me. I tried: clean project, restarting Eclipse, closing-&-opening the project, creating a new .scala file. No joy.
I'm using Eclipse 3.7 (latest stable), Scala IDE 2.0.0 and Scala 2.9 on Ubuntu Linux 11.10.
The symptoms in my case were:
My project was working, but then it stopped compiling for no apparent reason. The IDE didn't show any compilation errors for .scala files, but there were no .class files in the output directory & I got a NoClassDefError if I tried to run anything.
If I created a deliberate error in a .scala file, that did get picked up as a compilation error.
The .java files were registering errors due to the missing scala classes.
I suppose there's probably a boot-strapping bug somewhere in the IDE plugin for .java/.scala mixes. I've done hybrid projects with this setup without problems, so it's only triggered in some situations. I don't know what the trigger is, but once triggered, there's no nice solution.
I had moved my one and only class/object/application to a package, but had not added the package declaration.
sbt compiled and ran fine; eclipse would not
Adding the package declaration at the top of the file fixed it.
Scala 2.8.3 plugin; no compile error
I encountered this error too but after doing the suggestions here (cleaning, deleting Run Configuration etc), I realized that I set the workspace wrongly that is why the class is not being found.
An indication that this is a problem is when the same error occurs when you try to compile a java project.
I encountered this error (compilation worked in sbt but failed in eclipse) when I created a new package object called "common". Deleting the package object in eclipse caused the compile error to go away. There was nothing in it.
I was using sbt-eclipse to build the eclipse project. I'm using scala eclipse 3.0.0-vfinal-20130326-1146-Typesafe.