Building with IntelliJ - NetLogo/NetLogo GitHub Wiki
It's only worth involving IntelliJ if you plan to actually make nontrivial changes to the NetLogo source code.
If you just want to build, use the command line build. Involving IntelliJ won't make your life easier — it will make it harder, perhaps a lot harder.
I find this page crazy and can't be bothered to read the entire ginormous thing. Let me just give you a two-minute explanation of how to build with IntelliJ, since I use it pretty much everyday, and it's really not that complicated.
First, download IntelliJ. Community Edition is free and plentifully-featured. However, if you're a member of the NetLogo development team, you can contact me (Jason) for a license for Ultimate Edition. JetBrains provides us with free licenses for Ultimate Edition, because we're an open source project and they're totally awesome.
Once you have it downloaded, you need to set it up. This involves pointing IntelliJ at your Scala version and your local JDK, but that's not too tough, and I won't cover that with you here; you can find tutorials on this stuff all over the place if you search for it.
After that, any recent version of IntelliJ really ought to work fine for you with Scala. I don't know what all the troubleshooting garbage below is, but I don't recall ever seeing any of that stuff with IntelliJ. IntelliJ works pretty well for me. It's not unusual for it to complain and syntax highlight working code in NetLogo as being broken, but I can get over that. Some people can't. Whatever.
If you have IntelliJ 14+, you should just be able to open SBT projects (e.g. NetLogo, Headless, Tortoise, Galapagos) in IntelliJ. In older versions of IntelliJ, I suggest checking out the sbt-idea plugin. It's pretty handy! You just add a line to your plugins.sbt
, and then type gen-idea
in SBT to generate an IntelliJ configuration. It has saved me a ton of time, and I love it!
Note that the main NetLogo project requires a few more steps to get working. Basically, these steps will make all the NetLogo dependencies available for IntelliJ:
- Open build.sbt in the root NetLogo repository. Add the following lines right after line 130 (in the
settings(...)
):
managedDirectory := baseDirectory.value / "../lib_idea",
retrieveManaged := true,
- In a terminal, navigate to the root NetLogo repository. Run
./sbt netlogo/update
- Run
cp $(find lib_idea -name '*.jar') lib_idea
- Run
rm -rf lib_idea/bundles lib_idea/jars
- Remove the two lines you added from build.sbt
- Open Intellij. Open the NetLogo repository (root directory) as an Intellij project. DO NOT import it as an SBT project.
If the following instructions are unclear, incomplete, or incorrect, please help by improving them! This is a wiki page that anyone can edit.
IntelliJ IDEA is a Swing-based IDE for the JVM, from JetBrains in Russia. It's free and open-source. (There is also a commercial edition.)
It can be specialized to support any programming language, and has been extensively specialized to support Java development specifically. There is also a fairly mature Scala plugin.
The full name is "IntelliJ IDEA", but some people call it "IntelliJ" for short, others call it "IDEA" for short. We'll call it IntelliJ.
In general, IntelliJ runs great on Mac OS X, Windows, and Linux.
The NetLogo build has received the most testing on Mac OS X, somewhat less on Linux, and much less on Windows.
If you're on a Mac, you'll need Mac OS X 10.6 or 10.7.
As of December 2011 we were using IntelliJ IDEA 10.5. Later and/or earlier versions may also work.
Recently we've started using IntelliJ 11. So far it seems to work. After some more time passes, we'll make it the recommended version.
You may want to use the nightly build of the Scala plugin, which is under continual improvement.
Before you can use IntelliJ to do NetLogo development, you need to get the command line build going first. See Building.
You can obtain IntelliJ from http://www.jetbrains.org.
Before launching, you'll want to give IntelliJ more memory.
If you are on a Mac, you can do this by editing /Applications/IntelliJ <version>.app/Contents/Info.plist
Search for the line(s) containing Xms and increase the Xmx from 512m to 1024m:
-Xmx1024m
There may be more than one such line (e.g. under VMOptions.i386
and VMOptions.x86_64
); change them all.
1024m should probably be enough. If your machine has lots of RAM you can give IntelliJ more. Feel free to experiment with this setting. Increasing it may improve IntelliJ's performance; lowering it too far may cause the build to fail.
Launch IntelliJ.
Before opening the NetLogo project in IntelliJ, you'll want to make sure you have the correct plugins. To Add/Remove/Update plugins, open the Settings Dialog (by clicking on the wrench), then scroll down and click Plugins.
Most importantly, you need to install the Scala plugin. To add a new plugin, click on the Available tab. Then scroll down to find the plugin that you want (in this case Scala). Click the plugin, then either right click on it to choose Download and Install, or click that little disk with an arrow near the top of the tab.
The only plugins required for NetLogo are Scala and Git (and/or GitHub). All others can be disabled, especially if you know you won't be using them. This should improve the performance of IntelliJ. As with the memory settings, feel free to experiment with the plugins on your machine to determine what works best.
After changing any plugins, you'll need to relaunch IntelliJ.
You have two choices for how you want to work. You can either have IntelliJ do its own Git checkout of the netlogo tree, or you can work with an existing Git checkout.
You can use the GitHub plugin, or the plain Git plugin. With the Git plugin the steps are:
- menu: Version Control -> Checkout from Version Control -> Git
- add a new repository by clicking the + button. This will ask you for a url.
- put
https://github.com/NetLogo/NetLogo.git
, or use the URL of your own fork of our repo
If all is set up properly you will now be able to browse the NetLogo repo.
Choose what you want to check out (the 5.x branch, another branch, or a tag), click it and click the Checkout button. This will take a few minutes to complete.
If you already have a checkout you cloned from the command line or some other Git client:
- menu: File -> Open Project...
- In the dialog, navigate to the base directory of your netlogo checkout. You should see it appear with an IntelliJ icon. This means that IntelliJ understands that it is an IntelliJ project. Click it, and click OK.
You may get some warnings about additional Git repositories, because the directories under extensions
and models
are in separate repos. We ought to configure this better (using Git subprojects or something), but for now, you can ignore the warning.
Finally, you might have to set the JDK for the project.
- menu: Project Structure (also that book and tetris looking thingy to the right of the wrench)
- click project, and then set the project SDK. You might have to add a new JDK if one isn't automatically detected.
- click New -> JSDK, then navigate to a JDK
Home
directory and choose it.
On Mac OS X, use Java 1.6. (The 1.4 and 1.5 directories are fakes, and 1.7 probably won't work.)
Don't forget to run the command line build (sbt all
) first before trying to build and run with IntelliJ.
To Build the code, click Menu -> Build -> Make Project, or control-F9. The first time you build, it should take a few minutes, because IntelliJ has to build all of the code. But, successive runs it only needs to build what has been modified. Running code and tests automatically builds the code before the run, so it isn't necessary to build the code. However, it is helpful when you just want to see compilation errors.
To Run, near the top, next to the green play button is a drop down menu. Make sure "App English" is selected, and then click the green play button. This will first build the code (see above), then will launch NetLogo with the freshly compiled classes.
To Run a test, right click on the class and click Run "Classname", or click the test and type Control-Shift-F10. Simple as that.
To Debug, do exactly the same as above, but instead of clicking the green play button, click the button next to it with a little bug on it.
To Debug a test, right click on the class and click Debug "Classname", or click the test and type Control-Shift-F9. Simple as that.
The following error may occur when trying to compile NetLogo:
Scalac internal error: class java.lang.reflect.InvocationTargetException [sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25),
java.lang.reflect.Method.invoke(Method.java:597),
org.jetbrains.plugins.scala.compiler.rt.FastScalacRunner.main(FastScalacRunner.java:66)][java.lang.ProcessBuilder.start(ProcessBuilder.java:460),
scala.sys.process.ProcessBuilderImpl$Simple.run(ProcessBuilderImpl.scala:68),
scala.sys.process.ProcessBuilderImpl$DaemonBuilder.run(ProcessBuilderImpl.scala:22),
scala.sys.process.ProcessBuilderImpl$AbstractBuilder.run(ProcessBuilderImpl.scala:97),
scala.sys.process.ProcessBuilderImpl$AbstractBuilder.run(ProcessBuilderImpl.scala:96),
scala.tools.nsc.CompileSocket.startNewServer(CompileSocket.scala:101),
scala.tools.nsc.CompileSocket.getPort(CompileSocket.scala:127),
scala.tools.nsc.CompileSocket.getsock$1(CompileSocket.scala:166),
scala.tools.nsc.CompileSocket.getOrCreateSocket(CompileSocket.scala:184),
scala.tools.nsc.StandardCompileClient.process(CompileClient.scala:46),
scala.tools.nsc.CompileClient.process(CompileClient.scala),
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25),
java.lang.reflect.Method.invoke(Method.java:597),
org.jetbrains.plugins.scala.compiler.rt.FastScalacRunner.main(FastScalacRunner.java:66)]sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.jetbrains.plugins.scala.compiler.rt.FastScalacRunner.main(FastScalacRunner.java:66)
Caused by java.io.IOException: Cannot run program "scala": java.io.IOException: error=2, No such file or directory
java.lang.ProcessBuilder.start(ProcessBuilder.java:460)
scala.sys.process.ProcessBuilderImpl$Simple.run(ProcessBuilderImpl.scala:68)
scala.sys.process.ProcessBuilderImpl$DaemonBuilder.run(ProcessBuilderImpl.scala:22)
scala.sys.process.ProcessBuilderImpl$AbstractBuilder.run(ProcessBuilderImpl.scala:97)
scala.sys.process.ProcessBuilderImpl$AbstractBuilder.run(ProcessBuilderImpl.scala:96)
scala.tools.nsc.CompileSocket.startNewServer(CompileSocket.scala:101)
scala.tools.nsc.CompileSocket.getPort(CompileSocket.scala:127)
scala.tools.nsc.CompileSocket.getsock$1(CompileSocket.scala:166)
scala.tools.nsc.CompileSocket.getOrCreateSocket(CompileSocket.scala:184)
scala.tools.nsc.StandardCompileClient.process(CompileClient.scala:46)
scala.tools.nsc.CompileClient.process(CompileClient.scala)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.jetbrains.plugins.scala.compiler.rt.FastScalacRunner.main(FastScalacRunner.java:66)
Caused by java.io.IOException: java.io.IOException: error=2, No such file or directory
java.lang.UNIXProcess.<init>(UNIXProcess.java:148)
java.lang.ProcessImpl.start(ProcessImpl.java:65)
java.lang.ProcessBuilder.start(ProcessBuilder.java:453)
scala.sys.process.ProcessBuilderImpl$Simple.run(ProcessBuilderImpl.scala:68)
scala.sys.process.ProcessBuilderImpl$DaemonBuilder.run(ProcessBuilderImpl.scala:22)
scala.sys.process.ProcessBuilderImpl$AbstractBuilder.run(ProcessBuilderImpl.scala:97)
scala.sys.process.ProcessBuilderImpl$AbstractBuilder.run(ProcessBuilderImpl.scala:96)
scala.tools.nsc.CompileSocket.startNewServer(CompileSocket.scala:101)
scala.tools.nsc.CompileSocket.getPort(CompileSocket.scala:127)
scala.tools.nsc.CompileSocket.getsock$1(CompileSocket.scala:166)
scala.tools.nsc.CompileSocket.getOrCreateSocket(CompileSocket.scala:184)
scala.tools.nsc.StandardCompileClient.process(CompileClient.scala:46)
scala.tools.nsc.CompileClient.process(CompileClient.scala)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.jetbrains.plugins.scala.compiler.rt.FastScalacRunner.main(FastScalacRunner.java:66)
The key line in the error is this one:
Caused by java.io.IOException: Cannot run program "scala": java.io.IOException: error=2, No such file or directory
Apparently fsc requires Scala to be installed on the system. (However, I tried compiling a Hello World program in Scala using IntelliJ and fsc and it worked fine, so I'm not certain this is the case. But it is apparent from the error that something is trying to call "scala").
Modify $PATH
to include the scala installation directory.
Try a nightly build of the Scala plugin.
Compilation errors may occur in SampleScalaExtension.scala
Right click on the "extensions" directory in the Project pane and select Mark Directory As -> Excluded. Use sbt to build extensions.
Compilation errors may occur in RunsPanel.scala
Right click on the plugins
directory in the Project pane and select Mark Directory As -> Excluded. Use sbt to build plugins.
When compiling NetLogo, you may get these errors in src/main/org/nlogo/log/XMLLayout.scala:
Line 27:
error: value getLoggerName is not a member of org.apache.log4j.spi.LoggingEvent
val loggerName = event.getLoggerName
Line 30:
error: value getLevel is not a member of org.apache.log4j.spi.LoggingEvent
attributes.addAttribute("", "", "level", "CDATA", event.getLevel.toString)
I have no idea what causes these errors. This is almost certainly a compiler bug because you can navigate to those definitions just fine, and they come up in the auto-completion lists. Those functions are clearly defined. Adding empty parens after the invocation doesn't get rid of the error either.
Just comment out those lines and hope nothing breaks. (Please update this section if you are aware of a better solution).
You may get this set of errors when trying to compile on Windows:
src\main\org\nlogo\lex\TokenLexer.java Error:Error:line (240)cannot find symbol variable LITERAL
Error:line (249)cannot find symbol variable KEYWORD
Error:line (257)cannot find symbol variable COMMAND
Error:line (267)cannot find symbol variable REPORTER
Error:line (274)cannot find symbol variable VARIABLE
Error:line (279)cannot find symbol variable CONSTANT
Error:line (284)cannot find symbol variable IDENT
Error:line (754)cannot find symbol variable BAD
Error:line (760)cannot find symbol variable COMMENT
Error:line (786)cannot find symbol variable CONSTANT
Error:line (791)cannot find symbol variable COMMA
Error:line (795)cannot find symbol variable OPEN_BRACE
Error:line (803)cannot find symbol variable CLOSE_BRACKET
Error:line (807)cannot find symbol variable OPEN_BRACKET
Error:line (817)cannot find symbol variable BAD
Error:line (826)cannot find symbol variable CONSTANT
Error:line (832)cannot find symbol variable BAD
Error:line (840)cannot find symbol variable COMMAND
Error:line (846)cannot find symbol variable CLOSE_BRACE
Error:line (851)cannot find symbol variable BAD
Error:line (864)cannot find symbol class Number
Error:line (866)cannot find symbol variable BAD
Error:line (866)cannot find symbol variable CONSTANT
Error:line (875)cannot find symbol variable OPEN_PAREN
Error:line (883)cannot find symbol variable CLOSE_PAREN
Error:line (892)cannot find symbol variable BAD
Note that this file is not under version control.
In TokenType.scala, there's an abstract sealed trait TokenType, and an object TokenType which contains a bunch of case classes derived from TokenType. I guess this is legal, although the self-referential nature of this definition seems a bit weird to me. I think the Scala compiler was supposed to emit a TokenType class that contains all the members of the TokenType object, including LITERAL, KEYWORD, and so on. But when I looked at the compiled class files, I saw that it actually emitted a bunch of classes of the form TokenType$LITERAL$.class, TokenType$KEYWORD$.class, and so on. Using these names instead of TokenType.KEYWORD, and appending them with .MODULE$, made the compiler see them again.
First import org.nlogo.api.* at the top of TokenLexer.java. Then replace all occurrences of TokenType.SOMETHING with TokenType$SOMETHING$.MODULE$ in that file.
If you can search and replace via regex, then the following trick will do it:
'''Find:''' TokenType\.([\w]+)
'''Replace with:''' TokenType$\1$\.MODULE$
This resulted in some additional errors:
For this line:
scala.Either<String, Double> result = org.nlogo.api.Number.parse( text ) ;
I got the error: cannot find symbol class Number
I didn't see a Number class in org.nlogo.api, but I saw a NumberParser class. I think this was the intended one, so just change the line to:
scala.Either<String, Double> result = org.nlogo.api.NumberParser.parse( text ) ;
You may get the following errors in AutoConverter1Tests.scala when compiling NetLogo in IntelliJ with fsc, the fast scala compiler:
src\test\org\nlogo\compiler\AutoConverter1Tests.scala Error:Error:line (15)error: not found: type AutoConverter1
new AutoConverter1()(Compiler.Tokenizer2D)
Error:Error:line (71)error: not found: value AutoConverter1
test2DAnd3d("4.2pre4", "to setup clear-all end", "to setup " + AutoConverter1.clearAllAndResetTicks + " end")
Error:Error:line (72)error: not found: value AutoConverter1
test2DAnd3d("4.2pre4", "to setup ca end", "to setup " + AutoConverter1.clearAllAndResetTicks + " end")
C:\Users\serg\Dropbox\NetLogo\src\test\org\nlogo\compiler\AutoConverter2Tests.scala
Error:Error:line (5)error: Version is not a member of org.nlogo.api
...
I'm not sure what the cause is, but the errors go away when you switch to the regular Scala compiler:
- Go to Settings -> Compiler -> Scala Compiler
- Uncheck "Use fsc (fast scalac)".
You get this runtime error when opening a model in NetLogo:
java.lang.RuntimeException: coding error, bad translation key: compiler.SetVisitor.notSettable for Errors
at scala.sys.package$.error(package.scala:27)
at org.nlogo.api.I18N$BundleKind$$anonfun$2$$anonfun$apply$2.apply(I18N.scala:65)
The files used for internationalization are out of date because you haven't built using sbt in a while. When building with sbt, the following files (which are under version control):
- dist/i18n/Errors_en.txt
- dist/i18n/Errors_es.txt
- dist/i18n/GUI_Strings_en.txt
- dist/i18n/GUI_Strings_es.txt
Get copied into here (where they are not under version control):
- resources/Errors_en.properties
- resources/Errors_es.properties
- resources/GUI_Strings_en.properties
- resources/GUI_Strings_es.properties
If any of the files in dist/i18n
are updated, you will need to manually copy them into the resources directory.