Existing State

Implementation of most Java editing features needs a model of Java source code (like ASTs). The model that is currently used is the model provided by javac(star). NetBeans is in fact using a modified fork of the
JDK's javac. In the fork the signatures of the APIs are unmodified, although the behavior and internals are sometimes tweaked. NetBeans itself is providing another layer of APIs that enhance the javac ones.

The Java editing features (like code completion, formatting, errors, etc.) are mostly written against the (javac or NetBeans) API only, although they sometimes expect the modified behavior (e.g. specific spans for AST nodes, especially for input with compile-time errors). Some of the core modules (java.source.base, java.source, spi.java.hints, etc.) are also using javac internals.

The usage is direct - there is no intermediate API, the Java editing features call directly methods on the model API. There are NetBeans APIs that provide access to the AST, but walking though the AST, etc., is mostly done using the javac APIs directly.

(star) The Java compiler in JDK. The relevant javac APIs are javax.lang.model.**, javax.tools.** (although parts of this API are supersedded by NetBeans APIs), javax.annotation.processing.** and com.sun.source.**.

Using javac from the JDK

In the jdk-javac branch, the NetBeans internals are changed so that they can run with unmodified javac from the runtime JDK. This requires running on JDK 9 or later, as it depends on model APIs added in JDK 9. nb-javac can be installed, in which can it would be used instead of the runtime javac. This should mostly lead to the existing state, except for bugs and very few exceptions.


  • avoids a direct dependency on nb-javac (dependency on the javac APIs remains)
  • to some degree, allows experimentation with new language features - running on the JDk that supports the new features should result in the same errors reported inside the IDE as would be on the command line, although the IDE features (like code completion, highlighting) are unlikely to understand the new features, unless they are very simple.


When running without nb-javac, there are several caveats. A probably incomplete list:

  • error recovery is different in nb-javac and vanilla javac, which may lead to some features not working properly, like code completion no working, or spurious errors in the editor
  • partial repare (reparsing only the current method, if the user is only typing inside a method, then NetBeans may try to only reparse that method) does not work
  • erroneous source not supported for Compile on Save
  • parameter names may sometimes be missing in the code completion
  • during the initial index scanning (compiling), the processing must fit into the memory (the nb-javac based scanning tries to process the files one-by-one if the processing does not fit into the memory)
  • during refactoring/find usages, the processing is slower (parsing is done file-by-fileh2. Existing State
  • requires JDK 9 or later to run

The above can be (except for bugs) resolved by installing nb-javac, or it may be possible to partially mitigate some of the problems. A tricky problem in this branch is:

void test(Map<? extends String, ? extends Number> map) {
        map.entrySet();//assign return value to a new variable here

Which will produce incorrect results (on the jdk-javac branch, with or without nb-javac).

Additional caveats:

  • the core modules still depend on the javac internals
  • the IDE behavior depends on the platform's javac behavior, so this is harder to test and maintain
  • support for new language features is more tricky, as it needs to compile against JDK 9 versions of the APIs
  • No labels