Hi,
I've taken some time to investigate the issue I described lately. In
summary: When I try to start the SimpleShapes examples from my IDE,
the extenderbased example works fine, while the servicebased example
gives me exceptions:
ERROR: Error starting
file:../servicebased.circle/target/servicebased.circle-1.0.0.jar
(org.osgi.framework.BundleException: Unresolved constraint in bundle
1: package; (package=javax.swing))
According to [1] Felix should load javax.swing and make it available
to all bundles that import it. I had a look at the generated MANIFEST
in the servicebased bundles, and they import javax.swing. Clearly the
framework does export javax.swing. Otherwise the example would not
work when starting Felix from the command line and then installing and
starting the bundles. So that was no explanation.
The next thing I did, was checking, why the extenderbased example does
work but the servicebased doesn't. There had to be a difference
somewhere. And yes, I found one :) The extenderbased bundles do not
import javax.swing at all.
While the servicebased bundles provide their icons for the toolbar as
javax.swing.ImageIcon objects in their service properties, the
extenderbased bundles specify the path to their icons in the MANIFEST
(as bundle header). To make that clear, have a look at the Activator
of the servicebased circle, line 54 (btw: dict should be renamed to
props):
dict.put(SimpleShape.ICON_PROPERTY, new
ImageIcon(this.getClass().getResource("circle.png")));
The servicebased host's ShapeTracker, just has to obtain that Icon
(have a look at line 146 in that class):
Icon icon = (Icon) ref.getProperty(SimpleShape.ICON_PROPERTY);
Now compare that to the extenderbased example. The extenderbased
circle's MANIFEST has an entry:
Extension-Icon: org/apache/felix/example/extenderbased/circle/circle.png
and the extenderbased ShapeTracker is responsible for creating Icons
from that path (line 128):
String iconPath = dict.get(SimpleShape.ICON_PROPERTY);
Icon icon = new ImageIcon(bundle.getResource(iconPath));
So that explains, why the extenderbased example does work. Since the
host is not controlled by the framework when starting an embedded
framework, it can use what ever packages it wants. However it does not
answer the question, why the example works on Richard's machine but
not on mine.
By the way, I was able to get the servicebased example working in my
workspace by explicitly telling the framework to export javax.swing. I
just had to change the Activator line 155 to:
configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA,
"org.apache.felix.example.servicebased.host.service;
version=1.0.0, javax.swing");
Having all that said, I just wanted to ask you guys, if you have a
clue about all this.
Also Richard stated in JIRA [2] that he wants to keep differences
between the examples as small as possible. So I guess we should use
the same approach for both examples. That would be putting the icon
path into the bundle headers of the servicebased bundles. We can then
create the Icons by calling
serviceRef.getBundle().getHeaders().get(SimpleShape.ICON_PROPERTY).
OTOH having both approaches (bundle headers and service properties)
isn't to bad for an example that serves to show differences between a
servicebased and a extenderbased application.
What do you think?
Regards,
Benedikt
[1] http://wiki.osgi.org/wiki/Why_does_Eclipse_find_javax.swing_but_not_Felix%3F
[2] https://issues.apache.org/jira/browse/FELIX-3379