up: OtEquinox

OT-Specific Declarations in config.ini

The file configuration/config.ini contains fundamental settings for an OSGi installation. OT/Equinox adds a few additional declarations to this file, which are described here.

Mandatory declarations:

Adding mandatory declarations to the file config.ini is done through the "touchpoint" mechanism of the "p2" provisioning system, so everything happens automatically while installing the OTDT. This section only gives background for those who want to know what's going on behind the scenes.

osgi.hook.configurators.include=org.objectteams.eclipse.transformer.hook.HookConfigurator
osgi.framework.extensions=org.objectteams.eclipse.transformer.hook

These two declarations announce the OT/J bytecode transformers to the OSGi framework, by using the hooks described in http://wiki.eclipse.org/index.php/Adaptor_Hooks.

osgi.classloader.lock=classname

This line is also recommended in order to tell the framework to use a new locking strategy for all classloaders, which is known to work best for OT/Equinox. Due to the top voted bug reported against the Sun JVM (see https://bugs.eclipse.org/121737) additionally two vendor-specific options need to be passed to the JVM, which happens by the following entries in eclipse.ini (after -vmargs):

-XX:+UnlockDiagnosticVMOptions
-XX:+UnsyncloadClass
ot.equinox=1

This simple flag is needed to tell the OTRE that it runs inside OSGi.

osgi.splashPath=platform\:/base/plugins/org.objectteams.otdt

This declaration tells the launcher to show the splash screen which has been customized for the OTDT. Note, that also eclipse.ini contains a similar declaration, where precedence between both declarations is not perfectly clear.

Optional application specific declarations

Forced Exports

The config.ini file is also used to declare a specific form of decapsulation: forced exports.

Syntax:

(camel cased words are non-terminals, | denotes a choice, everything else on the RHS is literal)

ForcedExportDecls     ::= otequinox.forced.exports=ForcedExports
ForcedExports         ::= ForcedExport | ForcedExport,ForcedExports
ForcedExport          ::= BaseBundleID[PackageExports]
PackageExports        ::= PackageExport | PackageExport,PackageExports
PackageExport         ::= PackageName;x-friends:=AspectBundleIDs
AspectBundleIDs       ::= AspectBundleID | "QuotedAspectBundleIDs"
QuotedAspectBundleIDs ::= AspectBundleID | AspectBundleID,QuotedAspectBundleIDs

Simple Example:

otequinox.forced.exports=some.base.bundle1[some.base.pack1;x-friends:="some.aspect1"]

Complex Example:

otequinox.forced.exports=some.base.bundle1[some.base.pack1;x-friends:="some.aspect1,some.aspect2",some.base.pack2;x-friends:=some.aspect1],some.base.bundle2[some.base.pack3;x-friends:=some.aspect3]

The declaration is used to tell the framework that a given package within a given base bundle (e.g., some.base.pack1 within bundle some.base.bundle) should be exported to one or more specific aspects (e.g., some.aspect1), although the base bundle does not declare to export the given package.
The PackageExports part actually utilizes the syntax from a Export-Package: directive within a bundle's MANIFEST.MF, but note, that the x-friend part is actually mandatory here.

In order for this declaration to be effective, also the aspect's plugin.xml must contain an AspectBinding with a matching forcedExports element (only a package/list of packages, without the base bundle ID nor the x-friends part). With matching declarations in both locations in place, the given aspect bundle may indeed access classes from the otherwise inaccessible base package. Such usage should in fact be restricted to base imports and any uses that are allowed for base imported classes (this constraint is not yet enforced).

Future: the complex example above shows that declarations can soon become lengthy, yet the declaration must be given on a single line within config.ini. Therefore, we might consider to extract the forced exports declaration into a separate file and just leave a reference to this file within config.ini.

Compilation vs. Runtime:

The above explains how forced exports are enabled in the OT/Equinox runtime. As of #18 the compiler also interprets the declarations from plugin.xml and checks them against usage within the code.

Whether or not the compiler should report forced exports can be configured by the "decapsulation" warning token, or "Decapsulation (overriding access restrictions)" when using the compiler preferences dialog -- choose one of error/warning/ignore. The compiler will never tolerate access to a non-exported base class for which no forced export is declared.

References:

This feature was requested in #3 and initially implemented in r16490.
Checking by the compiler was requested in #18 and is implemented in r16541, r16542, r16543.