Scala+IDEA: Pros and cons of sbt and fsc - scala

I'm currently using IDEA's build mechanism with fsc for developing with Scala. It's still a bit slow and having to (re) start the compilation server is a pain. Many people here are suggesting SBT as a build tool together with IDEA.
What do you consider the pros and cons of each approach?

I tried both and in the end I prefer straight sbt for compiling.
Cons? I really miss being able to click through compile errors and fix the code directly, but... compiling in sbt is just much faster.
The nightly builds of the Idea Scala plugin can vary in quality/performance, but it's been getting better and better lately. The Scala plugin can now flag a number of errors that before I would have had to run compile to catch. (For example, I'm running nightly build 0.4.693 and the new method inspections have already been dead helpful.)
My advice for life with sbt on the command line: start sbt up and leave it running interactively as long as possible to take advantage of everything being loaded and JIT-ed.
sbt left running will fall over eventually but by giving it more memory in your sbt wrapper you can make that happen only rarely.
Here's the sbt launch wrapper that works for me.
java -Xms512M -Xmx1500M -XX:MaxPermSize=512m -jar `dirname $0`/sbt-launch.jar "$#"
My biggest issue with sbt 0.7 is that it frequently goes back and recompiles great swathes of files that seem only tangential to the code I was actually changing. (Even so, still faster than Idea and fsc!)
Good news: sbt 0.9 has some great incremental compile improvements. Unfortunately, the migration path from 0.7 to 0.9 is still in its early days. Mark Harrah's presentation at NEScala is online at http://www.nescala.org/2011/ if you're interested.
Useful plugins
http://github.com/mpeltonen/sbt-idea - easily create and keep your Idea project in sync with your sbt project
http://github.com/orfjackal/idea-sbt-plugin - lets you create run profiles for sbt from within Idea (I found this slower than running sbt at the command line last October - but I see orfjackal is still developing so I should give it another shot)

Related

intellij - Which Scala project do I create, Scala-Scala or Scala-SBT?

So Im learning Scala and using the Intellj IDE to make my projects with. When I click on New Project and then Scala I get the choice of
Scala
SBT
when i hoover the mouse over them I get additional info
Sample module with attached Scala SDK
SBT based Scala Project
Now I have played around with SBT before I downloaded Intellij and used it to compile and run some Scala code, so i kind of know what it is.
But I just don't know which one I should be choosing 1 or 2 and why someone would choose 1 over 2 or vise-versa?
Use SBT project . This will lead to Intellij doing the autobuild using SBT wityhout you having to rework the build each time.
The first time Intellij runs the sbt it will take some time to set itself up but eventually it will be far more rewarding.
Also as mentioned by Boris for portability you would want a standard build/compile tool.
I think there is not the solution to your problem. If you just want to try out Scala and the Scala SDK, the first choice is fine because you don't have any needs for an automated build. In my opinion is this your choice if you want to play around a bit without any overhead.
If you want to do a more real project I suggest to use sbt because it will build your project and manage your dependencies. This makes your project more flexible, easy to build for somebody else.

Gradual switch from Maven to SBT

Currently all our project builds with Maven on Windows. We were not successful with making incrementally compiled code to work in run time (50% of the cases it was failing with some kind of error), so to benefit from warm compiler and (maybe?) properly working incremental compilation we think about moving to SBT. However currently I have only one sprint to work on it, and I'm afraid to put all the eggs in a single basket and try to migrate whole project in a sprint. I need to find a way to make this change gradual, so I could advance one module at a time. So here are the main questions:
How can I include SBT modules in Maven build (or maybe vise versa, having my "parent" in SBT, yet part of the modules still building with Maven)?
How can we still benefit from IDE support (currently IntelliJ 13), like updated indices on changes in pom / Build.scala, task & goals invocation and so on?
Any advises on subject are highly appreciated.
Eventually we did the switch and don't regret it. Writing SBT tasks is easier, because it's plain Scala. Incremental compilation works now (used to fail in Maven with java.lang.InternalError: Enclosing method not found when deployed to JBoss) and build time is significantly faster. Unfortunately we did not find a way to make a gradual switch, so we had to take the risk. Incremental compiled jars still didn't work, yet Typesafe are about to fix this issue in 2.11.6

How to determine when Play! 2 must recompile all files?

When I edit a scala file in my Play 2 app, sometimes only a few files are recompiled, but often the entire codebase must be recompiled:
[info] Compiling 1 Scala source to /home/michael/code/superglot/target/scala-2.10/classes...
[success] Compiled in 1s
versus
[info] Compiling 2 Scala sources to /home/michael/code/superglot/target/scala-2.10/classes...
[info] Compiling 52 Scala sources and 1 Java source to /home/michael/code/superglot/target/scala-2.10/classes...
[success] Compiled in 13s
However I see no discernible pattern for when a full recompile is necessary. If I add somewhitespace to a model or controller class it may only compile that file, but doing the same to a comparable file will trigger a recompile.
I would love to have as many of my reloads be closer to 1s, because currently I'm waiting for a full recompile more often than not. I'd gladly refactor my code to make the areas I'm working on faster to reload, but I don't know what I could even do to achieve that. Are frequent recompiles normal for a typical Play 2 app, or is there something anomalous about mine?
In general, if you change the "source API" of a file, dependencies of that file are recompiled. The source API consists of the signatures of non-private methods and types. So, if you have a file that everything depends on, changes to signatures in that file may cause a lot of recompilation. Also, when an ancestor's API changes, all descendents must be recompiled.
You can get some additional information from last compile, such as what triggered other files to be recompiled. (In a multi-module build, last <project-name>/compile) You can
If adding insignificant whitespace causes other files to be recompiled, it is always a bug, often in scalac itself. An example of such a bug is SI-7361 (not that it is useful to anyone besides compiler developers!) that was worked around in sbt here. For these to be fixed, we need a reproducible test case. (Given the effort often involved in that, you might wait for 0.12.4 or 0.13.0 to see if those fix your problem.)
0.13.0 has some improvements that will hopefully reduce what gets invalidated when APIs change.
I think you are going for the slightly wrong approach here. As there is no way to successfully determine which changes will cause the full re-compilation, that path leads nowhere.
For learning purposes perhaps it is helpful to be aware of the compiler's internals to a better extent, but from a productivity perspective there is a much better choice available, and that is jRebel, who have been giving out free Scala licenses for years.
JRebel
From here, you can get a free Scala license within minutes.
Then go ahead and add this to the sbt config. It has to go straight into the sbt file.
Linux/Mac
java -noverify -javaagent:/opt/zt/jrebel/jrebel.jar \
-Xmx1024M -Xss2M -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled -jar \
`dirname $0`/sbt-launch-0.12.jar "$#"
Windows
set SCRIPT_DIR=%~dp0
java -noverify -javaagent:c:/opt/zt/jrebel/jrebel.jar \
-XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m -Xmx1024M -Xss2M \
-jar "%SCRIPT_DIR%\sbt-launch-0.12.jar" %*
At this stage, if you've done everything right, when you re-start the SBT console you will see that the jRebel Agent has been initiated and you will benefit from the real-time redeployment of your changes. When you Save in your IDE, JRebel will reload only the changes you've made.

Why does the Scala IntelliJ plugin take so long to start my application?

I go back and forth between Eclipse and IntelliJ for Scala development. IntelliJ's code-complete, refactoring and error-highlighting are all better (in my experience) but I end up going back to Eclipse because whenever I run a Scala application in IntelliJ, it goes through this very long compilation process that Eclipse somehow avoids.
I can see the status bar whiz by as it loads each individual class and then runs them through several phases. I know that scalac is slow in general, but it's much quicker to use the command line or Eclipse than it is to use IntelliJ.
Is anyone else seeing this behavior? Will turning on fsc support make a big difference?
Either use the IDEA SBT plugin to delegate compilation to SBT, or enable use of Fast Scala Compiler (FSC) under Settings → Compiler → Scala.
Otherwise IntelliJ starts and stops a scalac process to compile each batch of files, and this has some overhead.

Does SBT obviate JRebel?

My goal is to reduce Scala compilation times. I'm using Intellij IDEA 10 with Scala 2.8.1-RC1.
I've read that using SBT will reduce compilation times because it is clever about re-building only the files/classes that have changed since the last build.
I understand that JRebel has a very similar purpose. Is there any point in using JRebel instead of, or in addition to, SBT?
They do different things. SBT has a pretty speedy continuous incremental build system. JRebel dynamically reloads classes into a running program as they are rebuilt. It's something like a Java debugger's ability to modify a running program but with far fewer annoying limitations. SBT and JRebel are complementary.
You might also say that SBT obviates Hudson or other CI tools. Or that it obviates the red squiggly lines your IDE generates when you enter code that won't compile. But those tools are still useful even with SBT, and SBT offers lots of great features beyond CI and hot deployment.
It does obviate Maven.
SBT overlaps with JRebel for me a bit - like when I use SBT to continuously compile and redeploy a web application to jetty (~prepare-webapp). That feels quite a lot like using JRebel to continuously push changes out to a Java application container.
It offers "poor mans continuous integration" with quick code change detection and testing: http://devblog.point2.com/2009/07/27/scala-continuous-testing-with-sbt/
In general, SBT is the make/ant/maven replacement you should use for Scala. I'm constantly impressed with how it streamlines development, and I miss it when I go back to Java/Maven (even with JRebel). You should use it regardless of what other tools and frameworks you find useful.
Hope that helps :)