Hi Kevin;

Well, maybe the better way to understand what is going on is looking at the source code of the XMLInputFactory.newInstance().
I guess this method do something like the following:

  1. If the Thread Context ClassLoader is set, then use that class
     loader in order to lookup the
     META-INF/services/javax.xml.stream.XMLInputFactory file.
  2. If no Thread Context ClassLoader is set (null), then use the class
     loader which loaded the XmlInputFactory class (that is: the class
     loader of your bundle B)
  3. Else fall back on the system class loader and lookup the
     META-INF/services/javax.xml.stream.XMLInputFactory from the classpath.


In your working case, I think that the step 2 applies here, because you have embedded both API + Impl in bundle A. But, if you split the API and Impl in separate bundles A1 and A2, then it does not work, because in step 2, the class loader used to load the API (XMLInputFactory) is the one from bundle A1, not from A2 ...

Are you using the thread context class loader ?

From my side I do the following: I have written a special SPILoader bundle which uses the extender pattern: it listens to "Bundle Started" events. And when it detects that a bundle is started, then it checks if that bundle contains a META-INF/services/factory file. If so, then it loads the implementation (with the just started bundle.loadClass method) and registers it into the OSGi service registry. Hence, other client bundles can gain access to the API, from the OSGi registry, not using the Factory methods, like XMLInputFactory.newInstance().

So, in your case, you could retrieve your XMLInputFactory instance from your bundle activator, like this:

public void start(BundleContext bctx) {
ServiceReference ref = bctx.getServiceReference(XMLInputFactory.class.getName());
  XMLInputFactory factory = (XMLInputFactory) ref.getService(ref);
}

(of course, it would be nicer to use some dependency framework, like iPOJO, DependencyManager, SCR, etc ...)

However, you could argue that this solution is not applicable for third party libraries which invokes directly the XMLInputFactory.newInstance() method ... and you would be right ...


Regards
/pierre

Kevin Lohmann wrote:
Hi *,

I guess, I have a misunderstanding about classloaders in OSGi and i
appreciate, if someone can engross those thoughts.

Here's a specific situation:

Bundle A exports exports stax-api and implementation WoodStox. Bundle B
has an import on just the stax-api (javax.xml.stream). Bundle B calls
'XMLInputFactory.newInstance();'.

Now whats going on? According to
'http://java.sun.com/webservices/docs/2.0/tutorial/doc/StAX4.html' it is
looking for file 'META-INF/services/javax.xml.stream.XMLInputFactory'
"in jars available to the JRE". Bundle B finds this file and because
bundle A exports the WoodStox-classes, everything works fine.

But why? Remember: Bundle A has no exporting advice for META-INF (if
thats ever possible) and bundle B has no importing on that.

I try to split bundle A in two bundles: Bundle A1 contains the stax-api,
bundle A2 the implementation (WoodStox). But now, when I call
'XMLInputFactory.newInstance();' in bundle B the file
'META-INF/services/javax.xml.stream.XMLInputFactory' is NOT found.

I don't get the point and hope, someone can bring light into my/the
darkness.

Cheers,
 Kevin

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Reply via email to