Programming NetBeans Platform with IntelliJ IDEA

Introduction

The NetBeans Platform allows rapid construction of an
application that has some advanced capabilities,
including templates, undo/redo, auto update, and more. It is an alternative to Eclipse Platform
for those that wish to use standard Java Swing user interface instead of the Eclipse SWT user interface.
The NetBeans Platform grew organically from the lessons learned about application architecture learned by
the NetBeans IDE development team. Some of those
lessons included the need to isolate the various parts
of the application into "Modules" and the need to organize user interface items of interest into a hierarchy
of "Nodes".

The NetBeans Platform enjoys use on many Java Swing-based Java UI applications. Unfortunately, the NetBeans Platform
is coupled to the NetBeans IDE, and some developers prefer to use another IDE, such as IntelliJ IDEA. Most examples of NetBeans Platform
development are illustrated using the NetBeans IDE to perform the development. Fortunately, with the help of this article, you can
develop your NetBeans Platform application using IntelliJ IDEA.

IntelliJ IDEA is an IDE that used to be a commercial-only tool, but was
recently open-sourced. IntelliJ IDEA is favored
by some developers because it focuses on productivity and refactoring support. For those
IntelliJ developers that wish to develop on the NetBeans Platform, steps can be taken that will allow an IntelliJ developer
to work effectively on a NetBeans Platform application.

NetBeans vs IntelliJ notion of a Module

NetBeans defines a module as a cohesive chunk of code or a 3rd-party library with carefully defined dependencies
and available public packages. IntelliJ defines a module similarly, but without the ability to identify certain packages
as internal only. This means that you will sometimes have the IntelliJ IDE able to compile the application, but
NetBeans Platform will refuse to run it because one module is accessing a non-public
package of another module. Another reason IntelliJ IDE will compile the application but it won't run is because
the module dependencies are not set up properly. This means that IntelliJ has one module accessing a class in
another module without the necessary configuration in NetBeans to have it work.

To illustrate, we will use NetBeans Platform 7.3 Quick Start
to quickly create a NetBeans Platform Application using NetBeans. The result of following along with the example is a
NetBeans 7.3 Platform Application called "Word Processor" with five modules: WordEditorCore, WordEditorAPI, UppercaseFilter,
LowercaseFilter, and WordHistory. We will use IntelliJ IDEA 12.1.4 for the illustrations.
IntelliJ IDEA is free and open source.

Opening Word Processor Application in IntelliJ

Figure 1: Create New Project

Figure 2: Create New Project (Continued...)

Figure 3: Create New Module

In figure 4 when we configure the module, we exclude the build directory. This
prevents IntelliJ from overwriting compile outputs created by Ant or NetBeans.

Figure 4: Create New Module (Continued...)

Repeat the processes in Figures 3 and 4 for the remaining four modules: WordEditorAPI,
UppercaseFilter, LowercaseFilter, and WordHistory. Figure 5 shows what the dialog looks
like when done. We now have one IntelliJ module for each NetBeans module in our
project.

Observe that IntelliJ doesn't know anything about the NetBeans Platform. How does the
NetBeans build system know where to find the supporting jar files? The answer is in a
file called $wordproc\nbproject\private\platform-private.properties. The
variable $wordproc is the directory containing your word processor example
program. On the author's system, this is c:\wordproc. It contains one line:

These lines tell the NetBeans build system where to find the NetBeans Platform
jars and the IntelliJ project needs to know this information too. They are located
in a subdirectory named platform in the NetBeans IDE installation. One can also
obtain the smaller NetBeans Platform zip if the only requirement is to compile the
project. However, certain ANT targets in the NetBeans build system for deployment,
such as build-zip require something called a harness, which is not included in the
Platform zip. For this example, we will create an IntelliJ library that includes
all of the jar files in the NetBeans platform subdirectory, recursively,
but excluding locale-specific jars.

Once the IntelliJ library called "NetBeans Platform" is created, we need to add
it as a dependency of the IntelliJ modules in our application.

Figure 8: Adding the dependencies on NetBeans Platform.

After we have added the dependencies, we can rebuild the project. We have fewer
compilation problems now, but we are still unhappy, as shown in the next figure.

Figure 9: Second Compile of Word Processor Application in IntelliJ

It turns out that the NetBeans Platform example makes use of compile time annotations.
These annotations generate code as part of the compile step. We must tell IntelliJ
to go ahead and run the annotations and place them in a spot where we can see the
generated code from our IDE.

Figure 10: Enable Annotations Processing

After we have enabled annotation processing, we can rebuild the project. We have fewer
compilation problems now, but we have yet more configuration to set up, as is shown
in the next figure.

Figure 11: Third Compile of Word Processor Application in IntelliJ

The IntelliJ module WordEditorCore cannot find the package org.word.editor.api. That
package is inside the WordEditorAPI module. We need to add this dependency.

Figure 11: Adding Inter-Module Dependencies in IntelliJ

Repeat this process so that modules LowercaseFilter and UppercaseFilter also depend upon
WordEditorCore.

Figure 12: Fourth Compile of Word Processor Application in IntelliJ

While we do obtain a clean compilation, we still need to instruct IntelliJ where
the location of the generated source code is so that we can navigate to it in the editor.
For each of the five modules we will identify the "generated" subdirectory as a location
of source code. *The compilation is clean yet the red squiggly underline in
WordTopComponent.java shows that the configuration is still incomplete.

Figure 13: Identifying annotation-generated sources in IntelliJ

Observe that IntelliJ can now cleanly compile and navigate to the generated source code
of the application.

Debugging the NetBeans Platform Application from IntelliJ

It is possible to develop a custom launcher program that will launch the NetBeans platform
without the necessity to run either the NetBeans IDE or ANT-based NetBeans build system.
In the absence of such a launcher program, launch your application using ANT and connect
to it using a remote debugging profile. First, you will need to create a remote debugging
run configuration in IntelliJ.

Figure 14a: Creating the Remote Debugging Profile

Figure 14b: Creating the Remote Debugging Profile (continued)

Next, you will add the line with the debugging arguments to the suite's project.properties
file. On the author's system, this is located at $wordproc/nbproject/project.properties.
project.properties file. Remember to prefix the line that you copy paste from the
IntelliJ dialog with "-J".

Common Pitfalls

Failure to synchronize NetBeans and Intellij module dependencies.

If a module A depends upon a module B in the NetBeans universe, then the same should
be true in the IntelliJ universe. The same is true the other way. If you are editing code
in IntelliJ and you add a dependency between two modules, you need to make an
analogous change in your NetBeans module dependencies. This can be done by hand in
the modules' nbproject/project.xml file for the modules in question or using the
NetBeans IDE in the normal way.

Failure to add new packages to the list of public packages in a module.

If you add a new package to a module that you would like to be visible within other packages,
you need to edit the modules' nbproject/project.xml in the <public-packages> element to
include that package. Note that this is necessary because IntelliJ does not have the
ability to restrict visibility at the package level. This is a NetBeans capability that is
enforced by the NetBeans Platform runtime.

Summary

Some developers have acquired proficiency with the IntelliJ IDE and may wish to maintain or
develop an application based on the NetBeans Platform without having to use the NetBeans IDE.
This article has shown the necessary steps to allow the IntelliJ developer to edit, compile,
and debug a NetBeans Platform application from within IntelliJ IDE.

OCI partners with clients to assess, design, architect, engineer, manage and support Mission-Critical,
High Performance and Real Time systems. Our goal is to make IT solutions more open, scalable, reusable,
interoperable, and affordable. Please visit www.ociweb.com to learn
more about our service offerings, open source middleware technologies, and professional IT training.