Ticket #3 (closed enhancement: fixed)

Opened 6 years ago

Last modified 6 years ago

accessing classes from packages which are not exported by their plug-in

Reported by: stephan Owned by: stephan
Priority: major Milestone: OTDT_1.1.4
Component: otequinox Version: 1.1.3
Keywords: Cc: mosconi, AndreasWerner

Description (last modified by stephan) (diff)

Sometimes it is desirable to bind a role to a base class whose package is not exported from the base plug-in, i.e., the plug-in's MANIFEST.MF lacks a corresponding Export-Package directive.

OT/Equinox might want to selectively expose those classes by a new element of an aspectBinding declaration, like in

<aspectBinding>
   <basePlugin id="SomeBase" />
   <forceExport package="some.internal.package" />
   <team class="MyTeam" activation="ALL_THREADS" />
</aspectBinding>

With such aspect binding team MyTeam would be allowed to bind roles to classes from some.internal.package even if that package is not imported.

Note, that no other class or plug-in may access classes from this package, and even MyTeam may refer to some.internal.package only via import base.

Submitted by Andreas Werner & Marco Mosconi

Change History

Changed 6 years ago by stephan

  • status changed from new to assigned
  • description modified (diff)

Changed 6 years ago by stephan

  • cc mosconi, AndreasWerner added
  • milestone set to OTDT_1.2.0

I support the request, but cannot promise that it will be resolved for the next maintenance release.

Changed 6 years ago by stephan

Initial investigation gives these results:

  • It is possible to make changes to a bundle's manifest while it is being read by using a StorageHook and its method initialize(Dictionary).
  • At the time when the StorageHook is called, no information from the aspect registry (extensions to org.objectteams.otequinox.aspectBinding) is available.
  • AOSGi indeed uses a `StorageHook?, but
    • they don't require to read extensions
    • they need reflection to make the Headers instance holding the manifest information readable.
  • attempts to reload the manifest after the extensions are read resulted in duplicated BundleLoaderProxies (using AbstractBundle.update()). As a result the aspect still uses the non-augmented export list and fails to load force-exported classes.
  • In addition to run-time issues the compiler must be tought to find force-exported classes.

From this it seems, we need some more class loader trickery. When doing so, care must be taken not to duplicate classes loaded by regular loaders and by additional loaders implementing force-export.

Changed 6 years ago by stephan

Given the technical difficulties described in the previous comment, I re-thought the proposal resulting in the following proposal:

Instead of using the aspect's plugin.xml this super-decapsulation could be declared in the central config.ini (using the same names as in the initial proposal):

otequinox.force.export=SomeBase[some.internal.package]

This would emphasize that force-export is more fundamental than regular decapsulation. On the other hand I see that this would further complicate deployment. Any way I can offer to include the new proposal already in 1.1.4 for you to experiment with.

BTW: in the above example I would strongly suggest to use an x-friends directive to make clear which aspect may access the force-exported packages:

otequinox.force.export=SomeBase[some.internal.package,x-friends:="MyAspect"]

Note, that SomeBase, MyAspect are bundle names.

A complex example might than look like this (sorry, needs to be on a single line)

otequinox.force.export=org.base.bundle1[some.internal.package,x-friends:="com.my.aspect1";some.other.packgge,x-friends:="com.my.aspect1"],org.base.bundle2[some.hidden.pack,x-friends:="com.my.aspect2"]

etc.

Changed 6 years ago by stephan

After talking to resix, here is a combined proposal:

Considering the fact that force-export is even stronger than regular decapsulation we could require both entries: an aspect plugin requests that a package be exported from its base and the system config.ini is required to grant that additional export.

So if your aspect requests a force-export that is not granted in the config.ini you will get an error:

    Aspect Foo requests export of some.pack by plugin Bar, which is not provided in the current configuration.
    In order to acknowledge the export request please add the following directive to your config.ini:
    otequinox.force.export=Bar[some.pack,x-friends:=Foo]

Conversely, if config.ini declares a force.export which is not mentioned in the aspect's plugin.xml also an error will be thrown, leaving the aspect in a deactivated state.

Last, it should probably be enforced that all otequinox.force.export directives indeed declare an x-friend directive, in order to restrict the usage of force-exported packages.

Note, that for a runtime-workbench, e.g., the same directive can be provided as a vm argument (prefixed with -D) instead of explicitly using a config.ini.

Changed 6 years ago by stephan

  • status changed from assigned to closed
  • resolution set to fixed
  • milestone changed from OTDT_1.2.0 to OTDT_1.1.4
Note: See TracTickets for help on using tickets.