Netbeans Platform: Good, Bad and Ugly


The Good


The Netbeans Platform is incredibly simple to get started with. There are extensive tutorial based guides to get you started, like this tutorial about creating a CRUD application with zero code, or making a paint app, and videos too, not to mention Geertjan's Blog which goes into many advanced examples. If you're using the Netbeans IDE you also get a huge assortment of wizards to help you along with various annotation-based integrations. The wizards have excellent ANT support and pretty good Maven support as well. There are many advanced features in the box from window management, plugins, configurable key-bindings and an auto-update framework.

The Bad

When you want to do something advanced which isn't covered by a tutorial, you quickly need to roll up your sleeves and dig into the source code. For example, if you choose to migrate from the default ANT build to Maven, this guide is lacking if you aren't very familiar with Maven. Or even if you used the built in Maven wizard, there is no documentation that you need to run with the deployment profile to build the installers (if you're stuck on this one, it's "mvn package -P deployment"). Another big pain point for me was trying to create actions at runtime with localization which also showed up in menu's, this took lots of research before eventually creating a custom service, and they still didn't work for all cases. Even integrating my build with Jenkins was a headache.

The Ugly

When you're finished with your application, you still have a Java application. No matter how convenient and productive the language is there is still a strong bias against Java on the Desktop, and that bias doesn't seem to be going away (maybe JavaFX with native bundling will help sway people). Until it's easier to bundle your Netbeans Platform application with a native look and feel that bias isn't going anywhere.

UGS 2.0 to Netbeans Platform first impressions

For the past year Universal G-code Sender has suffered pretty severe feature creep. Lots of people had lots of good ideas, but it made the front end code confusing and hard to extend. In large part this is just because it's hard to compartmentalize a complex GUI. GRBL has had a lot of interesting features added in the past year which are begging to be leveraged, but UGS wasn't in a position to use them. With all this in mind I started trying to come up with a solution.

The first step was to decouple the "model" object from the GUI. Inspiration for this started nearly a year ago when Bob Jones implemented a web interface for UGS. Bob made a thin API layer which exposed a few simple functions and allowed him to build a completely separate web-based user interface. This pattern is known as Model-View-Presenter, and allows for multiple front ends which use the same back end code. It enhances test-ability of the business logic and helps facilitate a flexible front end. It didn't take more than a few hours to flesh out the rest of the functions this API needed so that the thin API exposed all of the back end features needed for the classic UGS GUI. After that it was a matter of re-implementing the Swing GUI to utilize the new API.

With the foundation laid it was time to consider what to build on top of it. Rugbymauri on github clued me into an idea that more experienced GUI developers have probably known for a long time: plugin based applications. Then he took it a step further and told me about the Eclipse Rich Client Platform (Eclipse RCP) and the Netbeans Platform. After some initial investigation I decided to pursue Netbeans Platform.

It took about a week for me to completely settle on the idea of a plugin based architecture. In the end, it was a perfect fit for UGS. The back end application already had features for sending status updates to any number of front end listeners. This has been used by the Visualizer from day one, it is a completely separate GUI component and it listens to the same back end events as the main GUI. Something like the Netbeans Platform would take this a step further and facilitate the creation of these modules - whereas in the classic UGS interface all these windows are managed in a monolithic "MainWindow" class.

Moving forward the concept of modules allows me to think about other features in a way that wont cause the code to feel bloated. For instance - how would a Gcode editor that can highlight some number of lines and have it displayed in the 3D visualizer? In the classic interface this would be a huge undertaking that would massively complicate the "MainWindow". On the other hand with a modular design there just needs to be a new "Editor" module, the Netbeans Platform handles sharing of the gcode file and provides APIs for binding selection events between the Editor and Visualizer. What would have been a week of effort could now be done in an afternoon or two. By the way, the Netbeans Platform also comes with all the modules created for the Netbeans IDE, so it already has GUI components for a code editor with breakpoints (Breakpoints? Maybe another afternoon).

There are a few areas that I'm not sold on yet, for instance UGS already has several observer API's and I'm not sure if I'll convert them to use corresponding Netbeans Platform features. Also the library wrapper modules are a little kludgy, especially if your project is built using a separate library jar like UGS is. Every time I rebuild my library jar I need to update the library wrapper module. The workaround I settled on was to modify my library's build script to dump the jar inside the library wrapper module, a side effect to which is that if I do a clean on that project it breaks the library wrapper.

The UGS Platform, UGS's 2.0 release, is currently in a proof of concept state. All the major integration has been done, now its a matter of creating all the different modules that exist in the Classic GUI. After that other features features of the Netbeans Platform can be leveraged for things like integrated Preferences and Configuration menu's, and default Window layout schemes.

Automated builds with Netbeans Platform 8.0.2

I've been converting UGS to run on the Netbeans Platform over the past week, and in general its been great.  The features and documentation I used while migrating UGS away from Swing were very well done. So aside from a couple hiccups, the Netbeans Platform has been great. Until a few days ago when I decided it was time to integrate my new changes with my Jenkins CI server.

It turns out that you can't build a Netbeans Platform application without connecting to the Netbeans IDE first. This has to do with the extra modules, platform components and build harness. Searching the subject online provides a lot of documentation, everything I've found is either out dated, contradictory, or I could only get it working with a new project and not my existing one.

The final solution was so simple, and minimally invasive that I wanted to create this blog post.

There are 4 interesting files for a Netbeans Platform build:
build.xml - Some documentation suggests adding a download-netbeans-rcp target here. That isn't needed. If you have a custom target you can put it here, otherwise there is no need to modify this file.
nbproject/build-impl.xml - This is loaded by build.xml, don't modify this file.
nbproject/project.properties - This file seems to identify your modules and the applications name, no need to modify this file either.
nbproject/platform.properties - Modify this file!
The Netbeans Platform has facilities built into its build script to download all required files. platform.properties is where you need to specify what it should download.
# These are used later in the build script
nbplatform.active.dir=${suite.dir}/latestStableBuild
suite.dir=${basedir}
harness.dir=${nbplatform.active.dir}/harness
# Provide some URLs
bootstrap.url=http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastStableBuild/artifact/nbbuild/netbeans/harness/tasks.jar
autoupdate.catalog.url=http://dlc-cdn.sun.com/netbeans/updates/8.0.2/uc/final/distribution/catalog.xml.gz
Thats it! It probably took me 5+ hours to find that. Now I can run "ant build-zip" on my Jenkins server and get a zip archive in return.