The NetBeans™ platform - Basic terms and concepts
19 Mar 2007 (last change: 15 Apr 2017)
Talking about the NetBeans™ platform requires a basic set of terms which are introduced here: module, plug-in, cluster, launcher, NetBeans™ runtime container, module system and class loading. In the course of the discussion the fundamental concepts of the NetBeans™ platform emerge, too.
Modularity not only is a general foundation of conceptual simplicity and separation of concerns. Moreover, it is the principal term to characterise the NetBeans™ platform as a whole. This article puts a focus on the most fundamental terms only; further terms are presented in follow-ups.
These terms will be discussed in this article:
- Module naming
- Module versioning
- Module dependencies
- Module life cycle and customisation
- Module types
- Public packages of a module
- Friend modules
- Module manifest attributes
- Module stability categories
- Module NBM file
- NetBeans™ runtime container
- Module system
- NetBeans™ class loading
Basic terminology and concepts
A module is the largest binary building block of any NetBeans™-based software. Managed within the NetBeans™ runtime container (see below) a module delivers a specific domain of functionality. Physically, a module is a simple JAR file with special manifest attributes; it contains code, resources (like images or locale-specific resource bundles), internal configuration data, and even documentation. Besides the JAR file, a module typically is associated with separate XML configuration files containing important information the runtime container needs to access beforehand. The NetBeans™ platform itself is composed of a set highly interdependent modules. Currently there are more than 45 modules which provide basic functionalities such as user interface components, update services, a virtual file system, and JavaHelp™ integration to mention just a few.
A module is referred to by three different naming conventions:
- First, a module has a human-readable module name like Module System API.
- Second, there is the code base name given in terms of the internet domain name of the one particular package that contains the module’s principal classes. In case of the Module System API this is
- Third, there is the update tracking name which denotes the module’s source directory. To verify this module name you should download a source distribution of the NetBeans™ platform. After having extracted the corresponding archive file you will see that all platform source rest in a directory like netbeans-src. Relative to this directory the sources of the Module System API project are located in directory openide/modules.
So, all three names
- Module System API,
refer to exactly the same module. In practice you will find all naming conventions used.
Versioning is another important issue when dealing with modules. All of the following kinds of versions may be assigned to a module:
- A build version, which typically is a date.
- An implementation version, which may be a free-form text.
- And a specification version like 1.0, 2.1 and so on.
Modules exhibit different types of dependencies. Commonly, a module depends upon other modules which contain the required classes or interfaces. Also, a module may depend on a particular Java™ package or even Java™ itself. And finally, it is even possible to create modules for specific operating systems only.
The case of inter-module dependencies needs two annotations:
- First, all dependencies must be given in a direct and explicit way, dependencies are not resolved indirectly.
- Second, dependencies imply that dependent modules must be compiled and linked against each other statically.
Module life cycle and customisation
The module life cycle encompasses all phases/events that a module as a whole experiences. Important ones are:
- Validation, ie checking for a correct manifest, missing dependencies, and other examinations.
- Installation/Uninstallation, ie making a module properly (un-)available to the platform.
- Activation/Deactivation, ie actually making use (or not) of a module; update, ie making available a more recent version of a module.
Developers may customise a module’s life cycle by providing a particular class equipped with special hook methods to modify the behaviour.
A module has one of three possible types that determine when and how a module is loaded:
- Regular modules are loaded when the application starts. From the NetBeans platform’s point of view regular modules are the default case. They may be activated (or synonymously: enabled) or deactivated (or synonymously: disabled) by application end users thus providing a configurability of the user interface. Regular modules themselves may in turn also activate or deactivate other modules. User interface component modules are quite obvious candidates for regular modules.
- Autoload modules are activated when another module depends on it and needs it. If a module’s purpose is just being a library then it is a good choice to make such a module an autoload module. Autoload modules are not under direct user-control.
- Eager modules are activated as soon as all of its dependencies are met. An eager module is not under direct user-control.
Public packages of a module
Any package of a module may be marked as a so-called public package. Thereby the contents of that package become accessible to other modules; non-public packages, on the opposite, remain inaccessible. This effectively allows to declare whole packages as public vs private, a feature which is not available in plain Java™!
Access to a module’s public packages may be even further restricted to friend modules. In this case an explicit list of friends must be provided. If a modules defines friends then all other modules cannot access its public packages.
It must be stressed that a module may either export its public packages to all other modules - by not providing friends at all - or just to the specified friend modules; a module must not mix both approaches at the same time.
A module’s manifest attributes
Most of the features already mentioned above are specified as attributes in the module’s manifest file. The
OpenIDE-Module prefix allows for easy recognition of the corresponding attributes. Notice however, that a manifest investigation should be done on the actual JAR files, not on the manifest sources.
Module stability categories
Modules of the NetBeans™ platform and IDE expose APIs of various stability categories. Consider these as rules provided and followed by the NetBeans team. The NetBeans™ API List gives an overview of modules and their corresponding stability. The following table gives a quick overview:
|Stability category||Description||Usage note|
|Official||A stable module in one of the official NetBeans name spaces
||Code against it.|
|Stable||A finished module whose API will not change within a major version; intended to be supported almost ‘forever’.||Code against it.|
|Devel||An uncomplete, proof-of-concept-like module intended to become stable. Incompatible API changes may occur rarely and are properly announced.||Code against it with a quite low risk of API changes.|
|Friend||A proxy for missing stable module; the API may change with each release.||Only for use among friend modules, do not rely upon!|
|Private||Though accessible, the API may change with each release.||Do not rely upon!|
|Deprecated||A deprecated module.||Do not use anymore!|
As these issues of the NetBeans API are very fundamental, it is strongly recommend to read the article How to Design a Module API even if you are not a NetBeans™ team member. Besides the philosophy behind the NetBeans™ API you will learn a lot about the API life cycle, the security of your NetBeans™ investment, as well as best NetBeans™ design practices.
Module NBM file
When packaged for web deployment, a module comes as so-called NBM (NetBeans module) file. An NBM file is just a ZIP file with file extension
.nbm. In contrast to a module’s simple JAR file an NBM file may contain additional data, such as meta-data and a security signature.
The official term plug-in is quite new in the NetBeans™ world. In the NetBeans 6.0 IDE you find plug-ins in menu Tools > Plugins:
There was no such dialogue in the predecessor NetBeans™ IDE 5.5. Instead, there was a Module Manager available in menu Tools > Module Manager:
A plug-in simply means a set of semantically related modules or as Tim Boudreau, Geertjan Wielenga and Jaroslav Tulach, the authors of the must-read book Rich Client Programming: Plugging into the NetBeans™ Platform, point out on page 22:
[…] if you are creating new features for the IDE or the platform but your feature set is composed of multiple modules, you might prefer to refer to those modules collectively as a single plugin.
Starting with NetBeans™ 6.0 the NetBeans™ platform itself is a single plug-in which of course consists of many modules.
A cluster means a set of modules put into a single directory for reasons of grouping semantically related plug-ins on a higher organisational level. Typically, NetBeans™-based applications like the NetBeans™ IDE are composed of clusters of plug-ins. A screenshot of a sample NetBeans™ IDE 6.0 installation directory in the next figure shows some typical clusters:
Except for directories bin and etc all others correspond to module clusters (directory etc holds cluster definitions, by the way). Most important, directory platform7 hosts the modules of the NetBeans™ platform. The ide8 cluster, for instance, contains the IDE related modules. Note, that if you are using a different NetBeans™ IDE (in terms of version or installer type) the directory names might differ.
To summarise: the top-down organisational levels in NetBeans™ are:
A launcher starts a NetBeans™-based application. The launcher is a shell-script on Unix®/Linux™/macOS systems and a native executable on Microsoft® Windows®. Its prime task is to instantiate the NetBeans™ runtime container.
NetBeans™ runtime container
The NetBeans™ runtime container is the execution environment that provides required services and functionalities to modules.
We have already learned that the NetBeans platform is composed of modules. So, which of them constitute the NetBeans™ runtime container? Unfortunately, the answer is neither found on the official NetBeans™ website nor in the NetBeans™ rich client book mentioned above. However, one of the book’s authors, Jaroslav Tulach (who is a NetBeans™ founder and architect), administers a Sourceforge project with an interesting article about the NetBeans™ runtime container and its constituent modules:
- File System API
- Module System API
- Utilities API
By the way, the article reveals that the runtime container is in production use since 1999. The self-contained dependencies of these five modules are underlined by the next figure:
What are the basic services, facilities and features supplied by the runtime container?
- The Bootstrap module provides the following basics:
- A general
JarClassLoaderand a specific
BootClassLoaderto get an application loaded.
- The definition of what a module is.
- A module manager for keeping a collection of modules.
- A command-line handler for interpreting the command-line options passed by the launcher.
- A general
- The Startup module contributes these essentials:
- The module system incorporating the bootstrap’s module manager.
- The so-called global lookup that gives access to service providers.
- An XML factory implementations for SAX and DOM parsers.
- A splash screen.
- The File System API module provides:
- Abstractions and implementations of virtual file systems for uniformly accessing files.
- A repository for the runtime configuration of NetBeans™-based applications; this repository is known as the system file system.
- The Module System API module:
- Embodies the abstract super-class of all modules:
- Allows to retrieve module information and dependencies.
- Embodies the abstract super-class of all modules:
- The Utilities API module containing a number of important things like:
- Lookup-related classes
- Task execution in separate threads
- System actions
- Exceptions handling
In the past the term module system has been used as a synonym for NetBeans™ runtime container. Currently however, runtime container is becoming the preferred expression in the NetBeans™ world. Accepting this change of meaning, we will use the term module system to denote the particular sub-system of the runtime container that is exclusively concerned with dynamic module management. This point of view is supported by the fact that the Startup module embraces the class
The key responsibilities of the module system are:
- Module detection
- Installation, uninstallation, and updating at runtime
- Activation and deactivation
- Registration and discovery
- And last but not least dependency management
NetBeans™ class loading
Class loading is an important issue one should be knowledgeable about when dealing with the NetBeans™ platform. Class loaders are a mechanism to obtain a class’s byte code, typically from a JAR file, to make it available for execution within the Java™ virtual machine (JVM). The JVM itself employs three main class loaders by default:
- First, the bootstrap class loader is responsible for loading the Java core runtime mostly from file jre/lib/rt.jar.
- Second, the extension class loader that cares about loading classes the from JAR files of optional packages.
- And third, the application class loader* that looks on the class path for something loadable.
Java™ class loading is determined by two basic principles:
- Class loaders exhibit parent-child relations (only the bootstrap class loader is parent-less).
- And the delegation of class loading which means that if a child class loader is requested to load a class, it first ask its parents to do the job.
In NetBeans™ (itself being loaded by the JVM’s application class loader) there is a boot class loader responsible for loading the runtime container. Moreover, each NetBeans™ module has a dedicated class loader of its own. This in fact is NetBeans™’s realisation of inter-module dependencies: the module class loaders constitute complex hierachies of parent-child relationships.
If you feel you should learn more about Java class loading in general, there is a highly recommendable article by Christudas Binildas. NetBeans™’s class loading is explained in greater detail in this article.
Copyright © 2007, 2017 by Volker Rautenberg. Some rights reserved.
Except where otherwise noted, this work is licenced to the public under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
The names of companies and products mentioned in this work may be trademarks, registered trademarks or service marks of their respective owners. Trademarks and service marks are used for referential purposes only and are not intended to infringe the rights of the mark owners.