ModuleInstall
class. Other classes in the package are not useful to module
authors.
All modules are distributed and installed as JAR files. The basic
format should be rather familiar; classes constituting the module are
archived in the JAR, and special entries in the
manifest file are recognized by the IDE.
The basic idea for the format of modules is taken from the
Java Extension Mechanism.
The
Package Versioning Specification
is used to handle dependencies both between
modules and of modules to the system.
All modules have some set of basic properties that indicate which
types of features they provide, which Java classes implement these
features, and what special option settings should be used when
installing these features into the IDE. All of this information is
listed in the
manifest file
using the customary format, and NetBeans-specific attributes. The
Java Activation Framework,
as well as JDK-internal features such as support for executable JAR
files, was used as a model for how to specify the useful contents of a
JAR in a data-driven fashion: many modules will need no special
installation code other than attributes in the manifest. The
Enterprise JavaBean deployment
model is used for the standard sections.
JavaHelp
is used for the context help.
Please see a list of tips on writing modules,
installing them into the IDE, testing and debugging them.
To create the JAR, just use the standard JDK's
JAR
tool. You will need to add a custom manifest file, so use the
There are a few other global tags which are optional but encouraged:
All other tags are bound to a particular module
section. Naturally you may use other standard manifest attributes.
In summary, here is an example manifest file that could be included
with the JAR tool's If you have troubles with a manifest, check to make sure you have
the suggested extra blank line at the end. Some JDKs may have trouble
parsing it otherwise.
To use a main install class, just extend the
The The
Some module installer classes may desire to keep state across
IDE sessions, for example if they require specific instructions on
what to uninstall that can only be gotten during the installation
process. All installers are automatically
The primary advantage of using layers is that they are declarative
rather than procedural, so you can install many kinds of extensions to
the IDE's behavior without any Java code, only XML. A related
advantage is that unlike Some common things that layers tend to be used for:
Related Standards
To the greatest extent possible, NetBeans has designed the module
system to reuse standard technologies when they are sufficient, and to
follow the style of others when not.
How to Create a New Module
For basic cases, you should need to do very little to create a module
besides writing the basic source code.
Build a JAR
All module implementation classes must reside in a JAR file. If you
want to split up a large application into several pieces, perhaps
so as to make independent upgrades possible, you should do so by
creating multiple modules and relating them using versioning. Currently there is no support for
including native code in the module.
-m
option to specify the additional contents. (Note that
-m
will automatically merge the contents of your manifest
file with anything it would normally add, so e.g. signatures will be
automatically created properly.)
Writing the manifest
A module is recognized as such by the IDE, by virtue of its having
a special magic tag in the global section of the manifest:
OpenIDE-Module
. Its value should be an arbitrary
identifier (with a format similar to that of a Java package name)
identifying the module for purposes of upgrades and
dependencies. You are encouraged (but not required) to use as this
tag the name of a Java package containing the principal classes for
the module; this ensures that there will not be conflicts between
modules produced by different developers or institutions, provided
that you follow the JavaSoft recommendations on naming packages
according to an Internet domain name you control. See the section
on versioning for details on what this tag
is used for.
The presentation-oriented tags (display name and category, short and
long description) may be in HTML if you prefer; this should be done in
the standard Swing fashion, by beginning the text with the magic
string <html>.
OpenIDE-Module-Name
OpenIDE-Module-Name_fr
.
OpenIDE-Module-Short-Description
OpenIDE-Module-Long-Description
OpenIDE-Module-Display-Category
OpenIDE-Module-Description
OpenIDE-Module-Install
OpenIDE-Module-Layer
-m
option:
OpenIDE-Module: com.modulemakers.clip_disp/2
OpenIDE-Module-Specification-Version: 2.0.1
OpenIDE-Module-Implementation-Version: build-213a
OpenIDE-Module-Name: Clipboard Displayer
OpenIDE-Module-Name_cs: Prohlizec schranky
OpenIDE-Module-Description: com.modulemakers.clip_disp.docs.ClipHelpSet
OpenIDE-Module-Install: com/modulemakers/clip_disp/Installer.class
OpenIDE-Module-Layer: com/modulemakers/clip_disp/Layer.xml
Sealed: true
Name: com/modulemakers/clip_disp/DisplayClipboardAction.class
OpenIDE-Module-Class: Action
Module authors are strongly encouraged to use the
API Support module
which among other advantages, provides interactive parsing of
manifests that can help the beginning API developer immediately see
how the IDE will parse his manifest, including possible parse errors.
Using a custom module class
With the OpenIDE-Module-Install
attribute, you may specify
a custom class which will handle any complex aspects of the module's
installation (or uninstallation). This class is only necessary to
write if the standard module sections and
layers do not
cover everything you need to do. Even if you do write such a class,
standard sections and layers may still be used for any part of the module's
integration into the IDE which is conventional--the main class need
only handle the exceptional parts.
ModuleInstall
base class. Your class must be able to be
instantiated as a JavaBean.
There are several methods which you may override, and may do anything
which is required to make the module cleanly enter and exit the
IDE. For example:
package com.modulemakers.clip_disp;
import org.openide.modules.ModuleInstall;
import org.openide.filesystems.FileUtil;
import java.net.*;
public class ModuleHandler extends ModuleInstall {
public void installed() {
// This module has been installed for the first time! Notify authors.
HttpURLConnection conn = (HttpURLConnection)
(new URL ("http://www.modulemakers.com/clip_disp/installed.cgi").openConnection ());
conn.getResponseCode ();
conn.disconnect ();
// Handle setup within this session too:
restored ();
}
public void restored() {
FileUtil.setMIMEType("test", "text/x-clipboard-content-test");
}
// Do not need to do anything special on uninstall.
// Tools action will be removed automatically.
// public void uninstalled() {
// }
public boolean closing() {
// Ask the user to save any open, modified clipboard contents.
// If the user selects "Cancel" on one of these dialogs, don't exit yet!
return DisplayClipboardAction.askAboutExiting ();
}
}
Some common things that module main classes tend to do:
installed
handler may do more or less what it
wishes--it will be called in a running IDE. The same applies to
uninstalled
and closing
. However,
restored
is more delicate in that it may be called
during earlier phases of IDE initialization. Therefore, it should
not use presentation-oriented features of the IDE, such as the
Explorer or Window System APIs. However, the other APIs are
acceptable to use in restored
, including the
TopManager's dialog notification methods.
ModuleInstall.updated(...)
method will be called just once when
a module is updated to a new version--when the new version is loaded
into the IDE for the first time (in a new session), the method is called
and the previous version number is accessible. Neither installed
nor uninstalled
will be (automatically) called in this case.
It is a module author's responsibility to make sure that new versions of a
module are capable of "cleaning up" obsoleted installations created by older
versions, as far back as a user is likely to be directly upgrading.
Externalizable
and module authors may decide to override the two methods of this interface
to read and write its state from an
object source. Typically you would want to serialize and deserialize
shared class fields
in the object using these methods.
It is a good idea to call the super methods as the first action when overriding.
Using an installation layer
Starting with NetBeans 3.1, you may specify the global tag
OpenIDE-Module-Layer
in addition to or instead of a
module main class; as a rule, use a layer for a particular task in
preference to a module installer, if you can. The tag value should
point to an XML file inside the module which is in the format
understood by
XMLFileSystem
.
Its contents specify some files that the module will add to the
system file system
controlling much of the IDE's configuration.
ModuleInstall
, there is no need
for multiple kinds of logic for module installation, restoration,
uninstallation, and upgrading; the "files" added by the layer are not
stored to disk and are loaded by the IDE in every session from the
XML, so when the module is uninstalled or upgraded its associated
files are correctly removed or changed, respectively, without any
extra work. (If the user customizes the files, however, their
customizations are stored to disk, and thus form a permanent
"patch" against the baseline configuration provided by the module.)
Currently only some parts of the IDE can be customized using files on
the system file system and thus by layers, but in the future more and
more things will be installable this way.
By default files listed in XML layers are not ordered in any
particular way, just as files found on disk would not have a
particular order. For purposes of some kinds of installation, it is
desirable to order data objects in data folders in a particular way -
for example, menus are
built from their menu items
in the order the instance-bearing data objects occur in the data
folder. The call
installed
method, and they will be automatically executed
by the IDE every time it starts up (recompiling first if needed). They
are generally intended to provide a way for users to customize some
aspects of configuration using arbitrary code as an alternative to a
module's restored()
method.
DataFolder.setOrder(DataObject[])
suffices to arbitrarily change folder order, but usually it is
desirable to create the proper order declaratively in the XML. For
this reason, DataFolder
understands special attributes
(set on the FileObject
forming the folder) which provide
relative ordering constraints on the objects in the folder.
Specifically: if there are data objects A and B in the folder,
represented by
primary files
afile and bfile, and there is an attribute
on the folder containing them named afile/bfile whose
value is Boolean.TRUE
, then the folder will attempt to
place A before B in its ordering. For example, the XML:
<folder name="SomeFolder"> <file name="first.txt" url="first.txt"/> <attr name="first.txt/second.txt" boolvalue="true"/> <file name="second.txt" url="second.txt"/> </folder>will cause the IDE to try to keep first.txt before second.txt. Things to remember:
DataFolder.setOrder(DataObject[])
is called, the explicit
order overrides the existing constraints. Subsequently added
constraints might have an effect, however.
The resource path pointing to the layer is automatically localized
by the IDE every time the module is installed or restored; if there
are locale-specific variants, they are merged with the main
layer. More-specific variants can simply add files to the set
installed by the module; however they take precedence over the
less-specific variants, and thus can replace files, or even remove
(suppress) them, using *_hidden masks as used by
MultiFileSystem
.
In fact, if module A depends on module B, then A's layer(s) will take
precedence over B's layers, and it may replace or remove files
installed by B. In the same way, any module may replace or remove
files installed by the core.
(Compatibility note: in NetBeans 3.1, only the most specific locale
variant of a layer is used, rather than merging them all together. You
may write layers which are conformant with this API and which also
work correctly in 3.1 by ensuring that all variants mention all of the
common files, as well as their particular overrides and masks.)
Modules can do three things with versioning:
Using versioning
Module versioning provides a way for modules to specify
which module they are (i.e. that one JAR is an upgrade from
another); which version they are; whether they have introduced
incompatible API changes since a previous version; and
(importantly) whether they depend on other modules or system
features, and if so how. While very simple modules may not require
special versioning support, this system should be used for any
module published on a general release schedule, or which it is
expected other modules may want to make use of.
At the heart of all these tags are the conventions used in the
Package Versioning Specification
created by JavaSoft. While their documentation should be referred
to for the full details and justification of this system, the basic
idea is that features (modules) have two versions: a
specification version, in Dewey-decimal format
(e.g. OpenIDE-Module
tag, whose value should be a unique
(programmatic) identifier for the module, as mentioned above. Not
be confused with the display name, which is freeform and may be
changed at will, this code name should not be changed
arbitrarily--pick a name and stick with it throughout module
releases.
OpenIDE-Module-Specification-Version
and the
OpenIDE-Module-Implementation-Version
tags.
OpenIDE-Module-Module-Dependencies
), Java packages
(OpenIDE-Module-Package-Dependencies
), Java itself
(OpenIDE-Module-Java-Dependencies
), or the IDE
(OpenIDE-Module-IDE-Dependencies
).
1.2.1
), and an implementation version,
which is some freeform text. Specification versions may be
incremented to indicate compatible API extensions, in which case
the check to make sure that the feature requested is available may
be done using a (lexicographical) compare on the Dewey-decimal
numbers (e.g. 1.0
< 1.0.1
<
1.1
). Implementation versions may be requested
according to an exact match only. Thus, specification versions are
generally used when you depend on some general and specified
behavior of another feature; implementation versions are used to
tie builds of different features together closely, as when you
maintain and release all the features yourself, and wish to
distribute them in a well-tested unit.
So, modules may specify either or both kinds of versions in their manifest, and correspondingly request such versions from other modules. The Versioning Specification provides similar numbering for (some, but not all) Java packages, as well as the core Java Platform APIs and Virtual Machine Specification. The IDE also has such versions which may be used to request a general level of Open API support (using specification versions) or a particular NetBeans build (using implementation versions).
Since the Versioning Specification does not address incompatible changes (those which would break existing code), but these are in practice occasionally necessary (however painful), both modules and the IDE itself may provide a separate integral number giving the incompatible release version. You may only request a particular release version, not subsequent ones, and you must specify the release version if there is one. It only differs from a complete change of the feature in that the module installer tool may prompt the user to make a "major upgrade" if a new release version of a module is available.
To use all of these tags once you understand them is not too
hard. First of all, feature names: a module is named according to
the OpenIDE-Module
tag, which should look like a Java
package name, but may be followed by a slash and release number
(e.g. com.mycom.mymodule/3
); the IDE itself is named
IDE
, again usually with a slash and release number;
Java packages are just named by the package name; the Java Platform
APIs are named by Java
; and the Java Virtual Machine
by VM
.
Now, a module may list its own specification and/or implementation versions using the tags above. To specify a dependency on other features, it may use some or all of the four dependency tags. The value of each will be a comma-separated list of dependencies of that general type, each of which can be of the form:
>
SPECVERSION
=
IMPLVERSION
OpenIDE-Module: com.mycom.mymodule/1 OpenIDE-Module-Specification-Version: 1.0.1 OpenIDE-Module-Implementation-Version: build99 OpenIDE-Module-Module-Dependencies: com.mycom.mysistermodule/1 = build99, com.othercom.anothermodule > 2.1, org.netbeans.modules.applet/1 > 1.0 OpenIDE-Module-Package-Dependencies: javax.television > 0.9 OpenIDE-Module-Java-Dependencies: Java = 1.2.1b4, VM > 1.0 OpenIDE-Module-IDE-Dependencies: IDE/1 > 1.0There is further special treatment for handling of package dependencies for several reasons:
Class-Path
must be
recognized and used; typically this attribute is used to actually add
extensions to the module classloader, while the Modules API attributes
are used to ensure that specific versions are available.
Here then is a sample manifest which depends on an extension called
again javax.television
, where it is known that a class
javax.television.TunerProvider
is part of the package.
The extension is stored in modules/ext/television.jar
relative to the IDE's installation directory:
OpenIDE-Module: com.mycom.mymodule/1 OpenIDE-Module-Package-Dependencies: javax.television[TunerProvider] > 0.9 Class-Path: ext/television.jar
Where can you get the version information to depend upon?
Package
class, or examine the manifest of the JAR you depend upon.
java.specification.version
and
java.version
; for the VM,
java.vm.specification.version
and
java.vm.version
.
netbeans.log
.
Important! If your module has compile-time references
to classes in another module, you must specify a
dependency on that module. This ensures that the modules will be
installed in the correct order; otherwise a
NoClassDefFoundError
or similar problem could result.
Standard Module Sections
Standard module sections permit the use of common extensions to be
simplified, as the use of an explicit module main class is not
required for these. In each case, the class file implementing the
extension must have a manifest entry containing the
OpenIDE-Module-Class
attribute, giving a code for the
extension type (see below); and may also have additional entries for
further customization.
Action
The class Action
installs a system action into the
IDE. Refer to the
Actions API
for details on how to create an action. The class must implement
SystemAction
.
By using this manifest section, your action will be available as
a "tool", i.e. it will appear (when enabled) in a list of all
extension tools in any popup menu (etc.) using
ToolsAction
.
Note that you do not need to use ToolsAction
directly for this purpose: it should already be attached as a popup
to all interesting nodes, as a menu item in the Tools menu,
etc. Just using the manifest tag ensures that your action will be
shown under such submenus.
Note: Actions may also be installed into fixed places in the Main Window's menus and toolbars (this can also include special components like palettes and so on), to keyboard shortcuts, or to the default popup menu of a data loader you did not write. The Actions API describes how to do all of these things--they do not require anything special in the manifest (besides use of a module install class).
Some types of actions make sense only for an object under your direct control. For example, if you are writing a data loader, you should specify which actions will be provided by default in its data objects' popups. This type of use does not require global installation; it can include standard IDE actions, as well as your own. Please see the Actions API for details on attaching an action to your own object.
Also, as mentioned in the Actions API, it is good practice for
all actions implemented by modules to be copied into logical
subfolders of Actions/ on the system file system (for
example using a module layer), since this folder is presented to the
user as a read-only "actions pool" they can use as a source of all
actions to customize their menus, toolbars, data object popup menus,
keyboard shortcuts, and so on.
Option
The class Option
installs this
system option
into the IDE's control panel, so that the module may have customizable
settings which will persist across sessions. See the
Options API for details
on how to write an option.
Loader
The class Loader
installs a
data loader
into the system
loader pool.
Refer to the
DataSystems API
for instructions on how to create a loader.
There are a couple of options which may be used to specify the relative precedence of data loaders, so that a more specific loader may take precedence over a more general one:
Install-Before: classname
DataLoader
constructor
for an explanation of how to use representation classes.
You may supply multiple class names separated by commas.
Install-After: classname
Install-Before
, except that the IDE will
attempt to install this loader after another, so as to give
it lower precedence.
Install-Before
and
Install-After
tags (if present) may fail to be honored
if there is no such registered data loader to compare to, or if the
tags are contradictory (imply a cyclic dependency); if so, the loader will still be installed.
By default a loader is placed at the end of the pool (i.e. lowest priority).
Note that these tags have no
effect on module install order or dependencies--for one thing,
loaders will be installed in the correct order regardless of which
order their providing modules are installed in.
You need not specify module dependencies on other modules simply because you use
the names of data objects in those modules in your install before and after
tags; the ordering hints will simply be ignored unless and until the other
module is installed, at which time they will take effect.
Debugger
The class Debugger
installs a new
system debugger,
replacing the previous one. Refer to the
Debugger API
for details on how to write a debugger.
Service
The class Service
installs a new
service type,
of which there may be many registered at once. Refer to the
Services API
for details on how to write a service type.
File system
The class Filesystem
installs a new
file system type
into the IDE, which may subsequently be instantiated by the user and
added to the
system repository.
Refer to the
FileSystems API
for details on creating a custom file system.
You may specify a couple of options for a file system:
Display-Name: some text
Display-Name_de
(in this
case, for a German locale).
Help: help ID
Note that this help ID is provided in the manifest, rather than on the file system itself, since it should not be necessary to actually create a file system instance to get it (which could have undesirable side effects), and it may be used in (e.g.) popup menus on the Repository permitting the user to add a new file system.
Node
installs a new
node
into some standard area of the IDE. You should also specify where to
place it with an attribute Type
, which currently may be
one of:
Environment
installs a node in the Explorer's
Environment hierarchy. This may be used for modules which need to
provide user-level access to some transient aspect of the module's
operation not otherwise apparent. For example, an HTTP filesystem
might want to provide a node under the Environment displaying
information about its cache, and permitting operations such as
clearing the cache.
Roots
installs a new root node for a whole new
hierarchy. These roots may be displayed as switchable tab panes in the
Explorer, to visually represent each root in parallel. Please do not
create a new root without a compelling UI justification.
Session
installs a new node in the Session
Settings area.
Refer to the
Nodes API
for details on constructing an appropriate node.
Clipboard convertor
The class ClipboardConvertor
installs a new
clipboard convertor
into the system, that may be used to perform transformations on the
contents of the system clipboard to data flavours that are not
otherwise supported by the
transferable.
Please see the
DataSystems API
for additional details.
JavaHelp
It is possible to add JavaHelp and context help capabilities to modules. The tag
OpenIDE-Module-Description
specifies a
help-set file according to the standard
JavaHelp specification.
The tag value gives the location of the help set within the module
JAR, and supports localization; for example, the description
com.mycom.mymodule.docs.TheHelpSet
might look for JAR
entries such as:
/com/mycom/mymodule/docs/TheHelpSet_en_US.hs
/com/mycom/mymodule/docs/TheHelpSet_en.hs
/com/mycom/mymodule/docs/TheHelpSet.hs
First of all, providing a help set means the IDE will permit users to see it via the normal JavaHelp viewer, and employ standard merging of navigational views. If you provide a home ID, a menu item linking to that home page will be added to the Help menu automatically, named according to the help set title; if it ends with an asterisk (*) it will be treated as a distinguished help set covering a prominent area of documentation. If you provide various navigational views, they will appear in merged form. Modules are strongly encouraged to provide a home ID, and views in the table of contents, index, and full-text search modes, making for a well-integrated help system.
When the help set is specified in the module, this permits the
IDE to associate context help with various features associated with
the module (or, technically, other modules--if you know their help
IDs and they do not themselves bind them). There are several ways
to associate help IDs with module features so that they may be used
by the IDE, mostly revolving around the API class
HelpCtx
.
Though this class has several constructors for different
purposes, the constructor which takes a Class
is the
most recommended, or the one taking a String
is also
acceptable. The constructor with a string directly uses that help
ID, which may be any string uniquely identifying the feature, and
associated with an HTML page using the map file; when passing in a
class object, this should typically be the class returning the help
object, and the ID will be the fully-qualified class name, which
avoids the need to separately choose a good help ID.
For example, a system action might include a method implementation such as:
public HelpCtx getHelpCtx () { return new HelpCtx (ThisAction.class); }Now the map file should include a line such as:
<mapID target="com.mycom.mymodule.ThisAction" url="this-action.html" />There are a number of different points in the APIs where you may specify a
HelpCtx
in this fashion:
Node.getHelpCtx()
DataObject.getHelpCtx()
TopComponent.getHelpCtx()
SystemAction.getHelpCtx()
NewType.getHelpCtx()
PasteType.getHelpCtx()
DialogDescriptor.getHelpCtx()
WizardDescriptor.Panel.getHelpCtx()
SystemOption.getHelpCtx()
ServiceType.getHelpCtx()
(applies equally to executors, debugger types, and compiler types)
HelpCtx.setHelpIDString(...)
.
This is especially useful for custom property editor components.
FeatureDescriptor
) attribute named
helpID
in a BeanDescriptor
, as described
by the JavaHelp specification in regards to beans. This will be
interpreted by any bean container (e.g.
InstanceDataObject
or
BeanNode
or *.ser
files)
that uses
InstanceSupport.findHelp(...)
.
This technique may also be used to add context help support to
the editor kits used in the
Editor API;
create the bean info for the subclass of
EditorKit
,
and this help will be used for the editor pane.
helpID
value
of a
Node.PropertySet
or
Node.Property
.
<homeID>
tag of a help set file; in
this case, the specified help ID is understood as applying
generally to the module. Typically it should be some sort of index
page. The IDE will automatically display such pages as the help for
a whole module, currently under Help | Contents.
The proper help page for the selected component, if there is
one, is displayed by the IDE by default using More user-friendly is the Update Center, a feature specific to
the NetBeans core implementation (i.e. its mechanism is not specified by
the APIs), which presents guided dialogs prompting users to
automatically upgrade modules or install new ones from an update server.
This functionality is provided by a module.
A proper module will store all of its configurable state using
options
(excepting service types, module externalization, etc.), and the
contents of these will be automatically carried over, one option at
a time (according to
option name
and
property name)
into the new module version using Externalization--so as long as your
option values can be externalized and reread into the new version, you
need not worry. Similarly, if the
First of all, when the IDE starts up, all previously-installed
modules are restored, calling the Now, when the IDE is running, modules may be installed into it,
possibly a cluster of them at once. In such a case, the IDE first
checks to make sure that all the prospective modules satisfy their
dependencies, either on system or Java features; already-installed
modules; or other modules in the prospective cluster. If any
modules fail their dependencies (or had syntactical errors in their
manifest files, etc.), they are removed from the list and the user
is given an explanation of what is missing. The remainder are then
ordered according to dependencies as above, and then installed in
that order.
Caution: it is forbidden to install modules which have
cyclic dependencies on one another, as the IDE would be unable to
determine which order to install them in! In fact, it will signal
an error and not install such modules. Generally such a situation
means that you should "factor out" the common required
functionality into a new module which the original ones will then
specify legal dependencies on.
Code which creates new classloaders and loads other code indirectly
should, however, be aware that the created classloaders are generally
subject to regular security restrictions, unless code is loaded from
within the IDE installation, or certain forms of The IDE currently loads each module in its own classloader,
which means illegal dependencies between modules will result in errors.
The Update Center supports certificate-based signing of
downloaded modules, so that the user can be sure that the contents
have not been tampered with or accidentally corrupted since their
creation.
F1
,
which calls
HelpAction
.
This applies to various visual components (when they have focus),
the current TopComponent
, and nodes (or the objects
they represent) when the node is selected in an Explorer window (or
custom windows based on
ExplorerPanel
).
Programmatically, you may also display help by calling
TopManager.showHelp(HelpCtx)
.
Deployment of Modules
This section describes how a module may be deployed to a user's IDE.
Downloading
One scenario is that the user will just download the module from
the Web somewhere as a JAR file. The module may be stored to disk,
and either dropped into the IDE's modules/
directory
(where it will be automatically installed upon the next IDE
restart) or manually installed from an arbitrary location using the
context menu on Global Settings | Modules. Children of this
node represent available modules and permit them to be dynamically
uninstalled or reinstalled.
Upgrades
Upgrades of modules can be customized by calling ModuleInstall.updated()
.
This permits you to manually remove obsoleted actions, delete old
templates, etc.--remove anything not handled by the module manifest
which is nevertheless part of the IDE's persistent state.
With the advent of XML layers, most of these reasons for using updated()
have disappeared.
ModuleInstall
class is externalizable and there is non-project state being stored
this way, you must ensure as usual that your externalization is
forward-compatible for upgrading to proceed smoothly.
Module install order
It may be possible for multiple modules to be installed at once, or
for a module to specify a dependency which is not satisfied. How
does the IDE handle such cases?
restored
methods on
their install classes if present. (Sections are installed before
this method is called.) If multiple modules are being restored
(which is normally the case), the IDE installs them in an
arbitrary order. However, if some of them specify
dependencies on other modules, the order may be adjusted so as to
make sure that the one specifying the dependency is installed after
the one it depends on.
Security
In the current API there is no particular provision for security in
modules: all modules are assumed to be trusted, and have access to
all of the IDE's features (including the abilities of the Java VM
running as an application) if they require them. So, users should
not install arbitrary modules from potentially dangerous
sources. Given the density of callbacks and the fine-grained object
model of the APIs, providing a thread-based security model for API
code is not feasible.
NbClassLoader
are used. When in doubt, explicitly define the protection domains for
classloaders you create.
UML Diagrams
Modules API general structure class diagram
Built on February 22 2001. | Portions Copyright 1997-2000 Sun Microsystems, Inc. All rights reserved.