Chapter 2. Structure of the NetBeans Platform: Let's Find Out What It's Made Of!

To give you an overview of how a rich client application is structured, and to show the relationship between the application that you're creating and the NetBeans Platform, this chapter will discuss the architecture of the NetBeans Platform. You will also be introduced to the independent building blocks of the NetBeans Platform and to the responsibilities that the runtime container handles for you. Finally, the structure of the NetBeans classloader system will be explained, together with the role it plays in applications built atop the NetBeans Platform.

NetBeans Platform Architecture

The size and complexity of modern applications has steadily increased over time. At the same time, professional applications need to be, before anything else, flexible, so that they can quickly and easily be extended. That makes it desirable to divide an application into distinct parts. As a result, each distinct part is a building block making up a modular architecture. The distinct parts must be independent, making available well-defined interfaces that are used by other parts of the same application, with features that other parts can use and extend.

The division of application into modules—that is, as logically interdependent parts—enhances the design of an application enormously. As opposed to a monolithic application, in which every class can make use of code from any other class, the architecture is far more flexible and, more importantly, far simpler to maintain. It is also possible to protect a class from access from the outside world, although such class-level protection is too finely grained to be useful to most applications. It is exactly this central aspect of modern client applications that the NetBeans Platform tackles. Its concepts and structures support the development and conceptualization of flexible and modular applications.

The basic building block of the NetBeans Platform is a module. A module is a collection of functionally related classes, together with a description of the interfaces that the module exposes, as well as a description of the other modules that it needs in order to function. The complete NetBeans Platform, as well as the application built on top of it, is divided into modules. These are loaded by the core of the NetBeans Platform, which is known as the NetBeans runtime container. The NetBeans runtime container loads the application's modules dynamically and automatically, after which it is responsible for running the application as well.

In this way, the NetBeans IDE is a very good example of a modular rich client application. The functionality and characteristics of an IDE, such as its Java language support or the code editor, is created in the form of modules on top of the NetBeans Platform (see Figure 2-1). That brings with it the great advantage that the application can be extended by additional modules and that it can be adapted to specific user needs, allowing particular modules that are not used to be deactivated or uninstalled.

Conceptual structure of the NetBeans IDE

Figure 2.1. Conceptual structure of the NetBeans IDE

To enable your applications to attain this level of modularity, the NetBeans Platform on the one hand makes mechanisms and concepts available that enable modules to be extendable by other modules, and on the other hand enables them to communicate with each other without being dependent on each other. In other words, the NetBeans Platform supports a loose coupling of modules within an application.

To optimize the encapsulation of code within modules, which is necessary within a modular system, the NetBeans Platform provides its own classloader system. Each module is loaded by its classloader and, in the process, makes a separate independent unit of code available. As a result, a module can explicitly make its packages available, with specific functionality being exposed to other modules. To use functionality from other modules, a module can declare dependencies on other modules. These dependencies are declared in the module's manifest file and resolved by the NetBeans runtime container, ensuring that the application always starts up in a consistent state. More than anything else, this loose coupling plays a role in the declarative concept of the NetBeans Platform. By that we mean that as much as possible is defined in description and configuration files, in order to avoid a hard-wired connection of these concepts with the Java source code. A module is described by its manifest file's data, together with the data specified in related XML files, and therefore does not need to be explicitly added to the NetBeans Platform. Using XML files, the NetBeans Platform knows the modules that are available to it, as well as their locations and the contracts that need to be satisfied for them to be allowed to be loaded.

The NetBeans Platform itself is formed from a group of core modules (see Figure 2-2), which are needed for starting the application and for defining its user interface. To this end, the NetBeans Platform makes many APIs and service providers available, simplifying the development process considerably. Included in this group (see Figure 2-2) are, for example, the Actions API, which makes available the oft-needed action classes; the powerful Nodes API; and the Options SPI, with whose help your own options dialogs can easily be integrated into the application. Next to these, there are also complete reusable components in the NetBeans Platform, such as the Output window and the Favorites window.

NetBeans Platform architecture

Figure 2.2. NetBeans Platform architecture

NetBeans Platform Distribution

Normally you don't need to download a distribution of the NetBeans Platform, since it's already a basic part of the NetBeans IDE, itself a rich client application built on top of the NetBeans Platform. When you develop your application in the NetBeans IDE and then create a distribution for your application, the NetBeans Platform is extracted from the NetBeans IDE distribution you use for development. However, you can also register multiple NetBeans Platforms in the NetBeans IDE. To that end, you can download a separate distribution of the NetBeans Platform from the official site, at http://platform.netbeans.org.

Let's now look more closely at the modules that make up a NetBeans Platform distribution:

The modules org-netbeans-bootstrap, org-netbeans-core-startup, org-openide-filesystems, org-openide-modules, and org-openide-util form the NetBeans runtime container. This is the core of the NetBeans Platform and is responsible for the deployment of all the other modules in the application.

The modules org-netbeans-core, org-netbeans-core-execution, org-netbeans-core-ui, and org-netbeans-core-windows provide basic underlying functionality for applications based on the NetBeans Platform.

org-netbeans-core-output2 is a predefined application module that provides a central window for displaying and working with application output messages. More about this module can be read in Chapter 9.

The module org-netbeans-core-multiview is a framework for multiview windows, such as those used by the Matisse GUI Builder, and makes an API available for similar views.

The module org-openide-windows contains the Window System API, which is probably the API most frequently used by NetBeans Platform applications. In this module you can find foundation classes for the development of application windows and, among others, the WindowManager, which gives you access to and information about all the windows available to the application.

A NetBeans Platform application's update functionality is provided by the org-netbeans-modules-autoupdate-services module. This module contains all the functionality required for discovery, downloading, and installation of modules into an application. The module org-netbeans-modules-autoupdate-ui provides the Plugin Manager, with which the user can choose and control updates to an application.

The org-netbeans-modules-favorites module provides a window that lets the user select folders and files—i.e., a filechooser integrated into a NetBeans Platform idiom. The actions added to folders and files via the Data Systems API can also be used in this window.

The module org-openide-actions makes a range of important system actions available, such as Copy, Paste, and Print, each of which can be implemented in a context-sensitive way.

org-openide-loaders is a very powerful module that contains, among others, the Data Systems API for the integration of data loaders that can be connected to specific types of data.

The Nodes API provided by the org-openide-nodes module enables a crucial concept in the NetBeans Platform, that of nodes. For example, nodes can be shown in an explorer view, have actions assigned to them, and be supported by property sheets.

The module org-openide-explorer provides a framework for the display of explorer views, such as the Projects windows and Files window that are used in the NetBeans IDE.

The module org-netbeans-modules-editor-mimelookup provides an API for the discovery of MIME-specific settings, services, and other objects, together with an SPI enabling creation of MIME-specific data providers. The module org-netbeans-modules-editor-mimelookup-impl is a special implementation of this SPI, used for the discovery of objects for which the System Filesystem is responsible.

org-netbeans-modules-javahelp contains the JavaHelp runtime library, while making an implementation available to the Module System API that enables it to integrate JavaHelp helpsets provided by different modules.

The Master Filesystem module org-netbeans-modules-masterfs provides a central wrapper file system to your application on the NetBeans Platform.

The module org-netbeans-modules-options-api provides an options window for user customizations and an SPI that enables you to extend the options window very quickly and easily.

The module org-netbeans-api-progress lets you control long-running tasks. The module org-netbeans-modules-progress-ui offers a visualization feature that enables users to end a task manually.

org-netbeans-modules-queries makes the General Queries API available for obtaining information about files that are handled by an application. On top of that is an SPI for creating your own query implementations.

org-netbeans-modules-sendopts contains the Command Line Parsing API and SPI, with which you can register your own handlers for dealing with command line arguments.

The module org-netbeans-modules-settings provides an API for saving module-specific settings in a user-defined format. To this end, it offers several useful settings formats.

org-openide-awt accesses the UI Utilities API, which provides many helper classes for the display of user interface elements in NetBeans Platform applications.

The module org-openide-dialogs provides an API for displaying standard and user-specific dialogs. In addition, this module also contains the Wizard framework.

org-openide-execution makes available an API for executing long-running tasks asynchronously.

org-openide-io provides an API and SPI for the display of input and output coming from data within the application. The module also makes a standard implementation available that enables the application to write to its output window.

The Text API in the module org-openide-text offers an extension to the javax.swing.text API.

The modules org-netbeans-swing-plaf and org-netbeans-swing-tabcontrol are responsible for handling the look and feel and the display of tabs, while the module org-jdesktop-layout is a wrapper for the Swing Layout Extensions library.

The org-netbeans-api-visual module makes available the Visual Library API, for modeling and displaying visual representations of data.

The module org-netbeans-spi-quicksearch contains the Quick Search API and SPI, which are new in NetBeans Platform 6.5. It provides the infrastructure to implement search providers for, e.g., menu entries, actions, or files. A central search field makes the search accessible to the user.

Additionally, it is possible to add modules to your application from the NetBeans IDE's distribution.

NetBeans Runtime Container

The basis of the NetBeans Platform and its modular architecture is the NetBeans runtime container. It consists of the following five modules:

Bootstrap:

This module is executed before any other. It carries out all registered command handlers and prepares a boot classloader, which loads the Startup module.

Startup:

This module deploys the application, at which point it initializes the module system and the file system.

Module System:

This module is responsible for the definition of modules, as well as their settings and dependencies.

File System:

This module makes a virtual data system available, with platform-independent access. Primarily it is used to load module resources into an application.

Utilities:

This module provides basic components, such as those required for intermodular communication.

Figure 2-3 shows the dependencies between these five basic modules.

NetBeans runtime container

Figure 2.3. NetBeans runtime container

The runtime container is a minimal subset of modules that NetBeans Platform applications require. Without other modules or settings being required, an application can be deployed containing these five modules. Directly after deployment it will shut down, since no further tasks have been defined. When the runtime container starts, it finds all available modules and builds from them an internal registry. A module is normally only loaded once it is needed. To that end, it is registered at startup. A module also has the ability to execute tasks at the time that it is loaded by the runtime container. That takes place by means of a module installer, about which more is discussed in Chapter 3. The runtime container also enables dynamic loading, unloading, installing, and uninstalling of modules, all of which occur at runtime. This functionality is for updating an application by the user (via the update feature) or for deactivating unnecessary modules in an application.

For a complete understanding of the deployment of a rich client application, it is also important to mention that the Bootstrap module (the first module executed) is started by a platform-specific launcher. The launcher is also responsible for identifying the Java Runtime Environment, which is required for starting the application. The launcher is part of the NetBeans Platform and is platform-specific, so that, for example, on Windows systems it is an .exe file.

NetBeans Classloader System

The NetBeans classloader system is an essential part of the NetBeans runtime container and a continuation of the encapsulation of modules and structuring of a modular architecture. This system consists of three different types of classloaders. These are the module classloader, the system classloader, and the original classloader. Most classes are loaded by the module classloader. Only in certain cases, such as when resources must be accessed outside a module, is the system classloader used. The original classloader loads resources from the classpath of the application launcher. The module classloader and the system classloader are multi-parent classloaders, having an infinite number of classloaders as their parents. The relationships between classloader types are displayed in Figure 2-4.

NetBeans classloader system

Figure 2.4. NetBeans classloader system

Module Classloader

For every module registered in the Module System, an instance of the module classloader is made available, by means of which every module obtains its own namespace. Primarily, this classloader loads classes from the module's JAR archive, by which it may load from multiple archives, as often happens with library wrapper modules. (You will learn more about this in Chapter 3.)

The original classloader is implicitly a parent classloader of every module classloader, and is the first on the parent's list. Further parents are those of related modules, on which dependencies have been set. How dependencies are set is defined in Chapter 3.

This multi-parent module classloader enables classes to be loaded from other modules, while avoiding namespace conflicts. The loading of classes is delegated to the parent classloader, rather than the modules themselves. In addition to the module JAR archive, this classloader is responsible for loading the locale extension archives (see Chapter 10) from the subdirectory locale, as well as the patch archives under the subdirectory patches, if these are available.

System Classloader

The system classloader is, by default, (as is the case with the module classloader) a multi-parent classloader. It owns all the instantiated module classloaders as its parents. As a result, it is theoretically possible to load everything provided by a module with this classloader. Even so, obeying the strictures of encapsulation, this approach should only be followed when absolutely necessary.

Access to the system classloader can be obtained in one of two different ways: via Lookup, about which you will hear much more later, as well as the context classloader of the current thread. This is the default (insofar as you have not explicitly set other context classloaders) of the system classloader.

ClassLoader cl = Lookup.getDefault().lookup(ClassLoader.class);

or

ClassLoader cl = Thread.currentThread().getContextClassLoader();

Original Classloader

The original (application) classloader is used by the launcher of the application. It loads classes and other resources on the original classpath and, after that, from the lib directories and their ext subdirectories. If a JAR archive is not recognized as a module (i.e., the manifest entries are invalid), it is not added to the module system. These resources are always found first: if the same resource is found here as in the module JAR archive, those found in the module are ignored. This arrangement is important to the branding of modules, as well as to the preparation of multiple language distributions of a particular module.

As before, this classloader is not used for loading related resources. It is much more likely to be used for resources that are needed in the early start phase of an application, such as for the classes required for setting the look and feel.

Summary

This chapter examined the structure of the NetBeans Platform. We began by looking at its architecture, the core of which is provided by the runtime container. The runtime container provides the execution environment of applications created atop the NetBeans Platform and also provides an infrastructure for modular applications. The NetBeans classloader system, which ensures the encapsulation of modules, was introduced and explained. Aside from the runtime container, many modules form parts of the NetBeans Platform, and we looked briefly at each of these. Finally, we noted that the NetBeans IDE is itself a rich client application consisting of modules that are reusable in your own applications.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.62.197