How Compile on Save works
The Compile on Save (CoS) feature is designed to make the "save / compile / run" cycle faster. This can be helpful for users accustomed to running and testing an application immediately after making changes to its sources. It utilizes *.class files produced while updating the internal data about projects. These files are always up to date, so there is no need to run Ant to regenerate them again before each run; they are simply copied from the NetBeans internal cache area to build/classes and the application is launched.
What Compile on Save is not
- CoS is not related to populating and updating the project class information cache, which is indicated by the label "Project scanning" in the IDE's status area.
- CoS is not related to error badges in the Projects view or error highlighting in the editor. All these features run out of the same underlying cache.
- CoS is not responsible for building JAR files.
How it works
The class files in the user directory (internal cache area) are always up to date; this is how the Java infrastructure works. The first time the application is run, the classes are copied to the build folder (e.g. build/classes) and the application is launched with this folder on its classpath. After any further modifications are made from the editor and saved, the class files are updated in both places: in the userdir and in the build folder. This makes any further application run even faster, since the application is launched immediately without copying anything (copying class files can take some time especially for large projects). The build folder is marked to contain files produced by the internal Java compiler. The Compile action is disabled since all sources are compiled automatically.
The classes produced by the internal compiler are not suitable to be put in a JAR, since they may contain special code to recover from compilation errors (see below). To build a JAR, Ant is used just as if CoS were disabled. At first the build dir must be cleared to avoid mixing classes produced by Ant with those from the internal compiler. This clean must be called explicitly (see Action Summary). Then the sources are compiled to the build dir and finally the JAR is created from them. The Compile action is enabled again. Saving modifications does not change files in the build folder until the Run action is called again to populate this folder with classes generated by the internal compiler.
Here is quick summary of exactly what the actions do:
- Run, Run File - the class files are copied from the userdir to the build folder if it was empty or contains class files produced by Ant. The build folder is added to the classpath together with JARs and other class files the project depends on, and the application is launched.
- Clean - the content of the build folder is deleted.
- Clean & Build - this action behaves like invoking Clean and then Build, i.e. the output folder is cleared and then Ant is called to produce class files.
- Build - the build action works only when the build folder is populated by classes produced by Ant, and will create a JAR. The user should call Clean first if the build folder contains classes produced by the internal compiler, to avoid mixing the files in one JAR. A warning dialog will be shown in this case, to let the user decide whether to call clean first, or disable CoS.
- Compile - the compile action is only available if the build folder contains classes produced by Ant. Otherwise the action makes no sense, since classes are compiled automatically.
Errors in sources
When developing an application it is very common that the code is not compilable all of the time; some parts of the code are not yet finished or are missing completely. The internal compiler can therefore compile sources which are uncompilable by external javac. Any code containing an error is simply replaced by code throwing an exception. The IDE also shows a warning before running a project containing errors. A consequence of this approach is that classes produced by the internal compiler may not be suitable for inclusion in a production JAR, which is why the IDE tries to prevent this from happening.
"Need to Compile" badges
The Need to Compile icon badge (a little wrench next to the node in Projects) is shown whenever the class file is not up to date, such as when the source file was changed after the last compilation. If the build directory is populated by classes produced by the internal compiler (e.g. after Run is selected) this cannot happen: compilation is always performed after the file is saved. If the build directory contains classes generated by Ant (e.g. after Clean and Build) the sources need to be compiled explicitly to get rid of this badge. The cause is described earlier: the class files in the build directory are not updated upon save in this case.
After external changes is necessary to do Clean & Build so the changes are propagated correctly to the Java infrastructure.
When there are two projects, one depending on the other, the setting of the launched project is significant. When the main project (the depending project) has Compile on Save on and is launched, the internal compiler generates classes in all projects the main project depends on (their settings are ignored). And vice-versa: when the main project has CoS off, Ant is used to compile all the projects in the dependency tree.
When CoS is not appropriate
The Compile on Save cannot be used in some specific cases. For example:
- The build script contains additional actions added by the user which are necessary for running the application. CoS does not use Ant to launch applications so these additional task would not be performed.
- There are important files in build/classes. CoS in not usable when there is another task (another program, or a modified Ant script) producing some files in the build folder, as this folder is cleared before build (see the Action Summary).
- Generating JAR: it is better to turn CoS off when user wants to build JAR periodically and run the application at the same time. When CoS is enabled the build folder needs to be cleared before building the JAR so there is significant slowdown in this case.
How to turn it on/off
Compile on Save is a project-specific option. It can be enabled/disabled in project properties, on the Compilation tab. By default it is on for all new project. For projects from NetBeans 6.1 or earlier the behavior is not changed (CoS is disabled). When the CoS setting is changed, the Clean action is performed automatically to avoid mixing classes.
Using Compile on Save in Maven Projects
In Maven projects, CoS is by default only turned on for tests. Go to the project properties dialog, Compile panel, to turn it on for main source execution as well.
Resources (as defined in the POM) are not copied before CoS-enabled Run/Debug is performed, but immediately upon editing. They are copied into the relevant output folder (target/classes for main sources and target/test-classes for test sources). TargetPath, Includes and Excludes of the resource definition are taken into account. Resources that shall be filtered are skipped. If you have changed such filtered resources, please perform mvn process-resources or mvn process-test-resources.
The .netbeans_automatic_build stamp file is placed into the relevant output folder to tell the IDE's Java infrastructure to start compiling and copying the class files there. The stamp file is created upon project open and before executing any action in the IDE (with the exception of Build Project and Clean & Build Project). This should ensure that while working with the project in the IDE, projects that have CoS enabled will have their classes compiled and resources copied all the time. This is useful, for example, when using JavaRebel; or when using Tapestry invoked via mvn jetty:run.
For web applications, resources are copied from the output folder to the expanded web application. When using an IDE-managed server deployment, the webapp gets redeployed eventually (depending on the application server).
Applies to: NetBeans 6.5+