mangen
- OSGi Bundle Manifest generator
Introduction
The OSGi model provides a very powerful and flexible framework for developing Java applications in a modular fashion with a high degree of control over classloading inter-dependencies between modules. Projects such as Oscar and Felix have recognised this power and implemented open source implementations of the framework. Adding to this is a growing availability of open source application bundles such as those offered via the Oscar Bundle Repository (aka OBR).
...
If you're not a Java developer, or you're not sure what OSGi is yet, then this tool is probably not for you!
Licensing
The mangen
utility was originally created as a copyrighted © work of Ascert LLC, and released as OSI Certified Open Source Software for use under the under the terms of the Common Public License
...
Included third-party libraries and contributions are copyrighted © works of their respective owners and are provided under the terms of their specified licenses.
Using mangen
Basic operation
Using mangen is very simple. Unpack the distribution file to an installation directory, change to this directory and type the following command:
...
Use of the word 'typically' is significant in the above descriptions. A basic set of rules and reports are included with mangen
to perform various useful tasks. This set is infinitely extensible, however, and mangen
places no restriction on the types of tasks that rules and reports can perform.
The exact rules and reports to be run are entirely controlled by user configurable properties as described below. If no properties are supplied mangen
will simply run, process the specified JAR files and exit.
Configuring mangen
with Properties
Properties to control mangen
behaviour can either be supplied on the command line using the normal -D
syntax or, for most cases in a mangen.properties
file. If the same property name is specified in both then the -D
command line property value will take precedence of the property file value.
...
No Format |
---|
mangen.osgi.level=3 ... mangen.rulesets=mangen-rule-R${mangen.osgi.level}- |
mangen.properties
The mangen.properties
Property is used to instruct mangen where to find it's properties file. By default, mangen
will look for a file named mangen.properties
in the same directory in which mangen.jar
was installed (i.e. lib/mangen.properties
). By including a -Dmangen.properties
setting on the command line a different properties file can be specified.
...
No Format |
---|
java -jar lib/mangen.jar -Dmangen.properties=my_mangen.properties my_app.jar |
mangen.osgi.level
There are two places in which the mangen.osgi.level
Property is used:
- internally within
mangen
to determine the correct format of Manifest headers to be processed and generated. - as a means to guide which rulesets are executed, using the variable-expansion syntax
At present, this Property should be set to a value of '3' or '4' (the default if not specified will be '3');
mangen.rulesets
Rules are the engine room of mangen
, providing the basic means for refining the mangen
detected import and export package sets e.g. removing un-needed or unused exports, supplying package version information, including undetectable package cases such as dynamic classloading.
...
Rulesets can be combined with variable-expansion to provide OSGi version dependent rules as shown the following example.
...
No Format |
---|
mangen.R4.syspackages=java\\..* ... mangen-rule-basic-0=Ignore imports(${mangen.R4.syspackages}) mangen-rule-basic-1=DontImportOwnExports |
See the Rules section for full details of the currently support rule types.
mangen-report-
Reports in mangen
work in a similar fashion to rules but without the ruleset concept. The set of sequentially numbered mangen-report-
properties will be scanned to determine which reports should be run e.g.
No Format |
---|
mangen-report-0=RuleReport .* mangen-report-1=BundleReport .* |
See the Reports section for full details of the currently support report types.
mangen.failonerror
If set on
will cause mangen
to exit with a System.exit()
error status of 3 if any errors occured. Typical usage is to allow an external build tool, such as Ant, detect that there were errors. Additionally, any error messages will also be sent to stderr
as well as stdout
if this property is set.
Default is on
.
mangen.failonwarning
If set on
will cause mangen
to exit with a System.exit()
error status of 5 if any warnings occured. Typical usage is to allow an external build tool, such as Ant, detect that there were warnings. Additionally, any warning messages will also be sent to stderr
as well as stdout
if this property is set.
...
Anchor | ||||
---|---|---|---|---|
|
Rules
The Rule concept in mangen
was adopted to avoid hard-coding the types of post-processing steps that a user would be able to perform on the mangen
generated set of package imports and exports. The rule syntax is as follows:
...
Details are included below showing whether a <rule-type> can be used in a global or a local context
AttributeStamp
Usable globally | |
Usable locally | |
Standard options | |
Rule specific options |
|
...
If the rule finds a package name pattern match and the package already has additional attributes an error will be thrown if the stamped attributes do not match the existing attributes. This could be the case as a result of either a previous AttributeStamp or Merge rule.
DontImportOwnExports
Usable globally | |
Usable locally | |
Standard options |
|
Rule specific options |
|
In many application cases it's not necessary for a bundle JAR to import it' own exports. This rule may be used locally or globally to remove from a bundle's import list any package which it also exports.
Ignore
Usable globally | |
Usable locally | |
Standard options | |
Rule specific options |
|
...
No Format |
---|
mangen.R4.syspackages=java\\..* mangen-rule-R4-0=Ignore imports(${mangen.R4.syspackages}) |
Merge
Usable globally | |
Usable locally | |
Standard options | |
Rule specific options | |
...
Anchor | ||||
---|---|---|---|---|
|
ProcessBundles
Usable globally | |
Usable locally | |
Standard options |
|
Rule specific options |
|
...
Being able to skip mangen
processing of bundle JARs is useful behaviour in a small number of instances, such as the ObrReport that will generally be run against existing bundle Manifest headers rather than mangen
generated sets of imports and exports.
...
No Format |
---|
mangen.rulesets=mangen-rule-initial- , mangen-rule-Ant- , mangen-rule-R${mangen.osgi.level}- , mangen-rule- , mangen-rule-final- mangen-rule-initial-0=ProcessBundles ... |
ResolveImportsToExports
Usable globally | |
Usable locally | |
Standard options | |
Rule specific options |
|
...
- cases of dynamic classloading
- certain third party JARs, such as Xerces, which use the awkaward-to-handle OSGi case of
Thread.getContextClassLoader()
to determine the classloader for dynamic classloading.
UpdateBundles
Usable globally | |
Usable locally | |
Standard options |
|
Rule specific options | |
...
Anchor | ||||
---|---|---|---|---|
|
Reports
Reports are really like a simplified case of rules. At present only a couple of simple reports are included.
All reports at present send their output to System.out
, which can of course be redirected to a text file if a persistent copy is desired.
RuleReport
This report will show any Rule generated output.
BundleReport
Report options | |
...
show-differences
- will show details of ADDED and REMOVED packages by comparing the generate set of import and export packages against the existing Import-Package and Export-Package attributes. If this option is omitted a simple list of generated imports and exports will be shownshow-local-rules
- will show report output from any local rules run for each bundle JAR
Anchor | ||||
---|---|---|---|---|
|
ObrReport
Report options | |
Produce a report for each bundle JAR that can be used as an OBR descriptor.
...
@@hdr:<header-name>@@
- include the attribute value of <header-name> from the bundle's Manifest. Themangen
attributes will be searched first, followed by the Main attributes@@
- process the list of imports and generate descriptor text based on themangen.obr.import.<obr-ver>
template@@
- process the list of exports and generate descriptor text based on themangen.obr.export.<obr-ver>
template@@import-ver@@
- will be expanded usingmangen.obr.import.ver.<obr-ver>
if an explicit version was included for the import package@@export-ver@@
- will be expanded usingmangen.obr.export.ver.<obr-ver>
if an explicit version was included for the export package@@pkg:name@@
- name of the import or export package currently being processed@@pkg:ver@@
- version of the import or export package currently being processed
Contents of the distribution file
The current mangen
distribution includes the following:
...
- Richard S. Hall - both for his assistance in the development and testing of
mangen
and for his contribution of the ASM based class scanning implementation.
Extending mangen
First things first. You need to be a reasonably proficient Java developer to undertake extending mangen
. If you're not, then you should consider a Java programming course or tutorial of some kind.
...
For detailed information, Javadoc API documentation for mangen
can be found @@api-index-loc@@.
Creating new Rule types
A rule type is in fact just a Java class which implements the com.ascert.openosgi.Rule
interface. If no package name is specified, these will be assumed to be in the com.ascert.openosgi.mangen.rules
package. Although somewhat less readable, a fully-qualified class name can be supplied for rule types in other packages.
At present, the simplest way to learn about creating new rules is to look at the source code for existing rules to understand how they're put together and what can be done in them.
Creating new Report types
Reports are similar to rules. A Report type is a Java class which implements the com.ascert.openosgi.Report
interface. Unqualified report types will be assumed to be in com.ascert.openosgi.mangen.reports
package, with the option to use fully-qualified class names if desired.
As with rules, the source code for the existing reports is the best place to learn about creating new reports.
Alternative class scanners
To parse the class files of an application mangen
needs a class file bytecode scanning library. So that alternative scanning tools may be used mangen
does not make direct usage of any library implementation. Instead a wrapper class is used which implements the ClassScanner
interface, and hence insulates mangen
from the specific details of different bytecode scanning tools. The mangen.scanner.class
property can be used to control which scanner implementation class is used.
At present, implementations of the ClassScanner
interface have been include for the ObjectWeb ASM toolkit and the Apache BCEL toolkit.
Ongoing Development
Change Log
Version 1.0.1
- Initial version submitted to Felix project.
- Package names changed and license headers changed to Apache license
OsgiPackage
classes changed to use Felix manifest handling classes.- ASM and BCEL sources removed and maven dependencies created to pull these in from repositories.
- Compiles and builds using normal maven build, but as yet doesn't create a standalone distribution which includes dependent jars and config
.properties
files. - No analysis work has been performed to determine enhancements and additional rules desirable to integrate with Felix build and take advantage of
mangen
class scanning.
0.1.x Versions
The 0.1.x versions of mangen
are the original versions developed to work with Oscar. The versions and documentation can still be downloaded from the OBR Sourceforge site. The change history has been maintained here for completeness.
Version 0.1.2
- Inclusion of ObrReport for generation of OBR descriptors [ oscar-osgi-Feature Requests-1221468 ]
- Removed "default" processing of JARs. Now an explicit ProcessBundles must be included to force JAR processing to take place. This allows reports, such as the new ObrReport to skip
mangen
import/export processing and just work from existing manifests. - default
mangen.properties
now explicitly lists each non java.* package rather than using wildcards, proved safer and more reliable when creating OSGi R4 manifests
Version 0.1.1
- Support for errors and warnings to cause non-zero exit status to be returned
- Fix for occasional failures to update bundle JARs [ oscar-osgi-Bugs-1218334 ]
Version 0.1.0
- First version
- Support for current OSGi Release 3 (R3) manifest headers, and basic support for proposed upcoming R4 headers
- Processing of JARs and directories containing JARs and parsing of contained classes using a subset of BCEL.
- Simple but extensible rule based engine for import and export set manipulation.
- Simple but extensible reporting engine
- Updating of process bundle JARs via an UpdateBundles rule
- Pluggable interface to allow alternative class byte code scanners to be used
Possible Enhancements
As with any piece of software, there are always more things you'd like to do than time available in which to work on them. This library is no exception.
...
Those which are more speculative have been left below.
Online usage within an OSGi environment
Extending the concept of Manifest-less usage comes an interesting possibility that a specific OSGi platform such as Oscar could be extended to load any JAR and automatically 'fix-up' a usable Manifest. This would require internal access/knowledge of the specific platform's implementation since the existing standard OSGi API would not supply sufficient details and access to the set of loaded bundle JARs. Additionally, it would probably need to be a "multi-step" process since until a largely complete set of bundle JARs were loaded it may not be possible to resolve all imports and exports. This perhaps implies some form of platform extension to allow a set of JARs to be passed to some form of "pre-load" mechanism capable of resolving their imports and exports within the JAR set, and possibly from existing loaded bundle JARs or even an external OBR.
Acknowledgements
Ascert is pleased to acknowledge the following projects, organisations and individuals whose tools have been used in the creation of this software:
...