- Purpose
- to provide the mechanisms to load (and unload) the auxiliary modules.
- Located
org.argouml.moduleloader
- Layer
- ?
Description
It is the modules' responsibility to connect and register to the subsystem or subsystems it is going to work with using that subsystem's API, Facade, or Plug-in interface.
A previous implemention of the module loader was located in org.argouml.application.modules.ModuleLoader with interfaces (Pluggable) in org.argouml.application.api, but it has been replaced by the interface described here.
For details on how to build a module see Modules.
What the ModuleLoader does
The ModuleLoader looks for module jars. It scans through all jars available in the ext directory. See Edit Settings Environment tab. If you turn on logging on the debug level while running ArgoUML you should be able to see what jar files it finds and what it does with them.
A module jar contains the classes, resources and a manifest file. The manifest file points out the class to be loaded. Also notice that the Specification-Title and Vendor must be specified correctly for this to work. [What does "correctly" mean in this context?]
Design of the Module Loader
Design:
We use a Loadable Proxy Pattern(?) for the modules.
Each module can be enabled and disabled individually. Dependencies between modules are allowed although not yet handled gracefully.
Each module is required to have one (1) class that implements ModuleInterface. That class (and all other classes that constitute the module) needs to be made available for some class loader, either by including it in the classpath or by letting the module loader hunt for it.
The modules are allowed to use all the APIs available from all the subsystems within ArgoUML and from other modules.
This is a big improvement over the old module loader in that:
We use the same APIs for the modules that we use within ArgoUML meaning that we implement and document it only once. This replaces the Pluggable class at every point where ArgoUML can be augmented.
We can have the module have different classes to register at different parts of ArgoUML.
We can have dynamic registrations that the module add and remove over time depending on some criteria that the module decides.
We don't need to search through all modules at every possible point where ArgoUML can be augmented.
Just as in the old solution, whenever a module needs to do something to ArgoUML, there needs to be implemented an API, possibly with registration/deregistration and callbacks.
All modules that can be found are examined at startup. They can be enabled and disabled individually from a special available modules window but have a default state that applies if the user hasn't taken action. Currently the default state is "enabled".
Dependency between modules!
If a module cannot be enabled because some other module needs to be enabled first or because some part of ArgoUML needs to be initialized first this is a problem. This is because the initial implementation is such that we have no register of dependencies.
The solution suggested is that the module loader persists in its attempts to enable a module so that the order among the modules is not important. For this to work the modules needs to signal when they fail. This is done by returning false or throwing an Exception from the module enabling method.
The module loader also provides an API that the well-behaving modules can use to test if the modules they depend on are enabled. The less well-behaving modules can just throw an exception when they fail to enable themselves properly.
If a module cannot be disabled, because some other module depends on it then this is signaled by returning false from the disabling method.
Where modules are loaded from?
The modules are loaded from the same places as in the old module loader. They can be internally i.e. available in the core jar file of ArgoUML, from the ext directory, or if running from JavaWebStart, they can be downloaded from the site.
To reduce the complexity of the downloads, let's use it in the simplest possible way: organize each module in a package and a jar file, have the jnlp-file list that jar file as a part and a package entry listing the classes, have a file listing optional classes and a GUI that allows the user to download them. Once a class is selected in the GUI it is loaded and, the JavaWebStart class loader will guarantee that it is available.
The scope of the modules.
Modules are always enabled and disabled on a per-application (per jvm) basis and not on a per-project or per-frame basis.