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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With