You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Marshall Schor <ms...@schor.com> on 2008/04/01 23:49:12 UTC

Building Eclipse plugins using maven-bundle-plugin - lessons learned

We switched to using the maven-bundle-plugin to build our Eclipse 
plugins for the Apache UIMA open source project.  After an initial 
apparent success, we slowly hit several issues that took a lot of 
experimental, time-consuming learning to overcome. 

The first issue we hit concerned "wrong wiring".  What would happen 
would be that several testers would try out the plugins, on various 
platforms (Windows, Linux, etc), and things would work.  An then one 
would report a failure.  We traced this to Eclipse's use of split 
packages.  (Background - You can see the list of Eclipse's split 
packages by going to the Eclipse "Help" and then searching for the 
terms:  split packages map)

Our first attempt was to wire a package to a particular bundle.  This 
worked, but "incrementally" - it would solve one problem, only to have 
some testing done later reveal yet another (different) instance of the 
split package problem. 

Since, in general, it could be the case that "both" sources of a package 
would need to be included, we changed the approach to use Require-Bundle 
for all the bundles that could supply classes for the split-package.  
This, by itself, didn't work - we think it was because the OSGi spec 
says that if you have both an "import-package" and a "Require-Bundle", 
the Import-Package takes precedence.  Here's the quote from the OSGi 
spec on this:

A bundle may both import packages (via Import-Package) and require one
or more bundles (via Require-Bundle), but if a package is imported via
Import-Package, it is not also visible via Require-Bundle: Import-Package
takes priority over Require-Bundle, and packages which are exported by a
required bundle and imported via Import-Package must not be treated as
split packages.

So - the next work-around was to add a negative pattern to the 
Import-Package for just those packages which were split - to avoid 
having them imported.  This seemed to work.

The next issue we ran into happened when we tried to use our plugins in 
Eclipse 3.2.x.  It seems that this level of Eclipse doesn't support the 
"uses" clause.  The fix here was to eliminate the "uses" clauses, by (a) 
using version 1.4.0 of the maven-bundle-plugin, and (b) adding a 
<_nouses>true</_nouses> instruction.  We also found a further motivation 
found for not generating the "uses" clause:  this note from the Eclipse 
project developers mailing list:  
http://dev.eclipse.org/mhonarc/lists/stp-dev/msg01624.html

Other issues we tackled:  the maven build of these plugins would work, 
but the Eclipse build would often give the following kinds of errors:
Access restriction: The method <some-method-name>() from the type 
<some-class-name> is not accessible due to restriction on required 
project <some-project-name>

If you opened the project properties and looked at the Java Build Path, 
and expanded the plugin-dependencies, you could, indeed, see there were 
"Access rules" for the <some-project-name>, but these rules would be 
missing the pattern which covered the case for the package where 
<some-class-name> lived. 

The fix for this (probably really a workaround?) was to add an explicit 
"import" for these packages to the POM's maven-bundle-plugin 
instruction: <Import-Package> to import these packages.  I don't really 
understand why this worked, or why the maven-bundle-plugin didn't import 
these automagically (the Import-Package list of packages included "*" as 
one of the items, which I think means to import all the packages that 
were referenced, but not locally available).

We'd be glad to learn of improvements we might make to our build process 
:-) .

-Marshall Schor


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: Building Eclipse plugins using maven-bundle-plugin - lessons learned

Posted by Stuart McCulloch <st...@jayway.net>.
2008/4/2 Marshall Schor <ms...@schor.com>:

> We switched to using the maven-bundle-plugin to build our Eclipse plugins
> for the Apache UIMA open source project.  After an initial apparent success,
> we slowly hit several issues that took a lot of experimental, time-consuming
> learning to overcome.
> The first issue we hit concerned "wrong wiring".  What would happen would
> be that several testers would try out the plugins, on various platforms
> (Windows, Linux, etc), and things would work.  An then one would report a
> failure.  We traced this to Eclipse's use of split packages.  (Background -
> You can see the list of Eclipse's split packages by going to the Eclipse
> "Help" and then searching for the terms:  split packages map)
>
> Our first attempt was to wire a package to a particular bundle.  This
> worked, but "incrementally" - it would solve one problem, only to have some
> testing done later reveal yet another (different) instance of the split
> package problem.
> Since, in general, it could be the case that "both" sources of a package
> would need to be included, we changed the approach to use Require-Bundle for
> all the bundles that could supply classes for the split-package.  This, by
> itself, didn't work - we think it was because the OSGi spec says that if you
> have both an "import-package" and a "Require-Bundle", the Import-Package
> takes precedence.  Here's the quote from the OSGi spec on this:
>
> A bundle may both import packages (via Import-Package) and require one
> or more bundles (via Require-Bundle), but if a package is imported via
> Import-Package, it is not also visible via Require-Bundle: Import-Package
> takes priority over Require-Bundle, and packages which are exported by a
> required bundle and imported via Import-Package must not be treated as
> split packages.
>
> So - the next work-around was to add a negative pattern to the
> Import-Package for just those packages which were split - to avoid having
> them imported.  This seemed to work.
>

That's correct, Eclipse transitioned to OSGi from their own legacy plugin
system which unfortunately had a number of split packages. In fact, the
Require-Bundle header was specifically added to help with this sort of
legacy situation.

However (as happens with a lot of software over time) plugin developers
copied this style and used Require-Bundle even when Import-Package
would be ok (ie. there weren't split-packages)

So there are still a lot of plugins out there that rely on Require-Bundle to
properly resolve dependencies - and, unlike Import-Package, this is hard
to automate as you don't necessarily know the correct symbolic name or
attribute to use on the Require-Bundle (not impossible, just more prone
to error).

hopefully as projects get refactored these split-package situations will
be less common - for now it still means trial and error when bundling :(

if you have suggestions for how to improve this, we'd be glad to hear

The next issue we ran into happened when we tried to use our plugins in
> Eclipse 3.2.x.  It seems that this level of Eclipse doesn't support the
> "uses" clause.  The fix here was to eliminate the "uses" clauses, by (a)
> using version 1.4.0 of the maven-bundle-plugin, and (b) adding a
> <_nouses>true</_nouses> instruction.  We also found a further motivation
> found for not generating the "uses" clause:  this note from the Eclipse
> project developers mailing list:
> http://dev.eclipse.org/mhonarc/lists/stp-dev/msg01624.html
>

well afaik it does support "uses", but unfortunately it has a performance
problem - hopefully this is/will be solved in future releases because the
"uses" clause helps maintain class-space consistency.

until then removing "uses" is ok... but I'd only do this for Eclipse plugins

Other issues we tackled:  the maven build of these plugins would work, but
> the Eclipse build would often give the following kinds of errors:
> Access restriction: The method <some-method-name>() from the type
> <some-class-name> is not accessible due to restriction on required project
> <some-project-name>
>

yes, I've also encountered this - there is a long running bug with how PDE
interacts with JDT where it thinks a class is not visible, but according to
OSGi rules it is (and the bundle works fine outside of Eclipse)

If you opened the project properties and looked at the Java Build Path, and
> expanded the plugin-dependencies, you could, indeed, see there were "Access
> rules" for the <some-project-name>, but these rules would be missing the
> pattern which covered the case for the package where <some-class-name>
> lived.
> The fix for this (probably really a workaround?) was to add an explicit
> "import" for these packages to the POM's maven-bundle-plugin instruction:
> <Import-Package> to import these packages.  I don't really understand why
> this worked, or why the maven-bundle-plugin didn't import these
> automagically (the Import-Package list of packages included "*" as one of
> the items, which I think means to import all the packages that were
> referenced, but not locally available).
>

importing the package (although not strictly needed by OSGi) works
around the visibility bug in Eclipse/PDE - note, there are also other
situations where compiling with a different target level (1.1 vs 1.2)
can lead to different imports, because of how Java class resolution
has changed between these bytecode releases.

(in early bytecode levels more superclass references were needed)

We'd be glad to learn of improvements we might make to our build process :-)
> .
>

well, if you find you're doing something again and again which could
be automated, let us know and we may be able to add it to the plugin.

-Marshall Schor
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>


-- 
Cheers, Stuart