|
|
|
Re: Service configuration error [message #1162233 is a reply to message #1160773] |
Wed, 30 October 2013 08:38 |
GianMaria Romanato Messages: 72 Registered: July 2009 |
Member |
|
|
Not sure this is you case, but a standard mechanism used by several Java API for locating a service implementation consists in scanning the application classpath for a file called META-INF/services/name.of.the.service.interface which contains the name of the implementation class to be used.
This is for example the case for the SAXParserFactory: when you try to create a SAXParserFactory instance, Java will look for META-INF/services/javax.xml.parsers.SAXParserFactory read the first file found in the class path, and instantiate the implementation class specified inside such file.
To locate the file and instantiate the class Java will use the Thread Context Classloader, because the code that performs the search is located in the RT.jar and as such its class loader (the JVM bootstrap classloader) has no visibility of the classes contained in your application class path (while of course the contrary is possible: application classes see RT.jar classes, because the application classloader is a son of the bootstrap classloader).
The above mechanism simply cannot work in OSGi, because of the class loader isolation that is at the basis of the OSGi specification. A bundle B that depends upon packages of a bundle A can see those packages, but A will never be able to load classes or resources from bundle B. Similarly, the RT.jar API will never be able to load implementation classes from application bundles.
Libraries that are more versatile and OSGi friendly usually allow the caller to pass in a class loader instance and use that class loader for locating files or classes. Libaries specifically designed for OSGi usually locate services via the OSGi service registry. If your library is not OSGi specific you have to hope that it supports passing in a class loader. In such case you should just pass the right class loader. You could get a bundle class loader via AClassFromThatBundle.class.getClassLoader() or you could write a ClassLoader proxy that wraps the Bundle class.
To better understand how class loaders work in plain JavaSE or JavaEE have a look at this http://www.idevelopment.info/data/Programming/java/reflection/Understanding_ClassForName.pdf
Then you should also check the OSGi specification and understand the substantial differences. At that point you will be able to diagnose all of these problems.
If the library you are looking at is not OSGi friendly at all, another possible solution could be using the Equinox Buddy-Policy manifest header http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fbundle_manifest.html
That certainly works in plain Equinox, but I never tried in Virgo. Also, keep in mind that that's an Equinox specific feature that will not work in other OSGi containers.
Finally, you may consider rewriting part of the initialisation code of the library. Maybe that could be as simple as subclassing a class and overriding a method.
GianMaria.
|
|
|
|
Powered by
FUDForum. Page generated in 0.07263 seconds