The goal of this post is to help get you running with a simple but real Scala project inside an IDE. By this, I mean a small project that has external JAR dependencies. JVM languages typically need some kind of build/dependency tool to get yourself up and running because of the JAR ecosystem. Sometimes just getting the project working with a build tool is enough. With Scala, I decided to use an IDE to help get acquainted with the language. I carefully chronicled all the headaches I ran into while getting up and running and this post will describe those issues and hopefully help ease the pain for others. These instructions worked on OS X.
I am not an expert on Ant, Maven, Buildr, or SBT but my experience with using an IDE has taught me that you want to setup a real build tool/dependency manager even if you use an IDE. An alternative option to what I describe here is to have your IDE to create proper Maven/Ant files for you, but I suspect that is pretty complex too. If you let the IDE manage dependencies for you by using the proprietary "project" format provided by the IDE you could create problems when you commit to version control. Others will pull down your project and have some or all of the following problems:
- If you didn't commit your dependent JARS, they will have to find them on their own and then add them as dependencies.
- If they don't use the same IDE you used they will be completely out of luck.
- Even if they do use the same IDE you used, it is bound to have directory references to your machine in the project property files that will not work for them.
So, we need an IDE and a build system.
I have chosen to go with IntelliJ. Read the rest of the section for why, or just skip to the next section. I have used Eclipse with Scala before, but it has always been buggy. I've really wanted to go with Eclipse for Scala because it is backed by Typesafe, but in my opinion it is still not ready. The last version I tried was the one announced here. It did not work well for me, with the following problems.
- Eclipse froze when I built my first Scala project. Everything was there when I restarted, but that is irritating. This happened with the latest version and the previous version on two separate computers.
- Import statements in the Worksheet was not working properly for me, and you still need to wrap code in an object to make it run in the Worksheet.
- I was getting ghost red-x compile errors on in the left margin for lines where there was no code.
- No support for plain Scala scripts, everything must be in an object or class.
IntelliJ did not have any of those problems.
For Scala, SBT is popular. The best thing you can probably do for yourself is to read the SBT docs before you start. Otherwise there will be a lot of guess work as you blindly copy code from the internet. My biggest problem with the SBT documentation is that it uses a lot of Scala class parameter syntax to describe the concepts. This can be overwhelming for someone learning SBT before they learn Scala. Still, it is worth powering through. One minor, but key point:
Typing a command after typing sbt on the command line is not the same as entering the SBT interactive REPL (by just typing sbt) and entering commands. This was a major source of confusion for me in the beginning. For example, to inspect a setting, you do not type
sbt inspect <setting>
You have to enter the REPL and type
Install SBT. Instructions are here
Once you install SBT, do the following to save yourself some future pain.
Set you permgen space higher for the JVM (this has something to do with space reserved for a tier of memory related to garbage collection). Create a file called .sbtconfig in your home directory and put this in it.
SBT_OPTS="-XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M -Xmx512m -Xss2m"
Install the sbt-idea SBT plugin. The instructions are on the page. This will allow SBT to create IntelliJ projects that are a reflection your SBT project configuration. That sounded confusing, but just go with it for now.
SBT needs the version of Scala it was compiled with to work, this is different from the version of Scala it will use to compile your projects. This can lead to confusion, so it helps to keep it in mind. The gen-idea plugin works nicely, but currently for some reason it adds the SBT Scala version as a dependency for your projects. This is wrong. Your project is only dependent on the version of Scala you are using for your project. To disable this, create a file in your home directory called .sbtrc and place the following line in it:
alias gen-idea=gen-idea no-sbt-build-module
- Open IntelliJ, choose "Configure" from the Quickstart menu that pops up. Then choose plugins and search for and install the Scala and SBT plugins. I am not exactly sure you need the SBT plugin, but it doesn't hurt. I believe it enables IntelliJ to use SBT to build your project, but it does not create the required IntelliJ config based off your SBT configuration (that is what the gen-idea SBT plugin does). You can read the documentation for the SBT plugin here.
Create your project
After all that we are now ready to create an actual project. Here is the main idea: You create a directory and a simple file to tell SBT what version of Scala you want your project to use. You then use SBT and the gen-idea plugin to create an IntelliJ project. You can then open this project in IntelliJ and everything will work. What is the difference between doing all this vs. just creating a Scala project in IntelliJ?
- IntelliJ requires that you tell it per project where your Scala home directory is. This is annoying.
- We use the SBT configuration to drive the IntelliJ configuration. You can just commit your SBT configuration files to version control, and others can generate the IntelliJ configuration if they wish to.
- The sbt-idea plugin can be run multiple times to sync up any changes you made to your SBT configuration with the IntelliJ configuration. For example, if you use SBT to add a jar dependency, you can run the plugin to add this JAR as an IntelliJ dependency (read: generate a bunch of XML files for IntelliJ).
Okay. Let's get started.
- Create a project directory wherever you want and descend into it.
Create a file called build.sbt. Put the following in it where
is the Scala version you want to use. Right now, I am using 2.10.1.
scalaVersion := "
If you do not do this, the sbt-idea plugin will create a project that uses whatever version of Scala it was compiled with (probably something like 2.9.2), which is not likely to be what you want.
Run the following command:
Open IntelliJ and then open the project (not import, it is already an IntelliJ project).
You're done. You can create a Scala Worksheet and trying something like
to see that you are in business.
Adding JAR dependencies
At this point, the most likely next complication will be that you need to use a Java or Scala library that is in a JAR. You could use the IntelliJ mechanism to add an "External Jar", but since we have made a point to make the IntelliJ configuration just a reflection of your SBT configuration, the best thing to do would be to add it using SBT and then run the
command again. There are two main ways to add an SBT dependency to your project- unmanaged and managed. The easiest to do is unmanaged- just create a
lib directory in the root of your project directory and drop the JAR you need in there. If you run
sbt gen-idea it will tell IntelliJ about it and everything will just work. However, if this is a project to be checked into version control, managed is probably the way to go. Just follow the instructions at the link above and then run
One last detail
You can tell IntelliJ to build with SBT instead of Make (or whatever its default is). I am not exactly sure what the advantages of this is (especially since you can always do your real build from SBT since the IntelliJ configuration is just a reflection of that), but I have seen situations where the Worksheet functionality did not work properly unless you did this. Follow the instructions here to do that.
Thanks for reading, please leave any comments or corrections.