Hi Tim,

First, the fact that you are doing this from outside of the OSGi framework 
might have been quite useful information to highlight up front. It changes 
everything! Just saying ;-)

Consuming services from outside OSGi when they are published from inside a 
bundle is pretty tricky… it can be done but you need to be very careful about 
the API package imports and exports.

In a “normal" situation, you have one of the following two scenarios:

a) The service provider bundle exports the API package, and the consumer 
imports it.
b) There is a separate API exporter bundle, and both the provider and the 
consumer import from there.

However in your situation, the “outside” (aka the OSGi system bundle) is the 
consumer and unfortunately the system bundle CANNOT IMPORT from ordinary 
bundles. So you have to do two things. First, arrange for the API to be 
exported by the system bundle, using org.osgi.framework.system.packages.extra. 
Then, make sure that the provider bundle imports the API from the system 
bundle. This part might be tricky because the provider bundle might be trying 
to export its own copy of the API, though hopefully it also imports to allow 
for substitution. You need to be careful to export from the system bundle with 
a version that satisfies the provider bundle.

If you get this wrong, and the provider bundle either uses its own package or 
imports it from somewhere that is not the system bundle, then the service is 
considered incompatible and it will be filtered out as I described in my 
previous email. It sounds like this is exactly what is happening, because you 
said the ServiceReference was null.

Finally I would point out that what you’re doing is an advanced use case for 
OSGi. It might be better to either get more experience with mainstream OSGi 
usage before tackling this level of problem, or perhaps get yourself some 
training or consulting from an expert.

Kind regards,
Neil


On 7 August 2014 at 04:23:40, Tim McIver ([email protected]) wrote:

Renato,  

Thanks for the response. You actually made me feel a lot better about  
myself! I have been struggling to understand how to use OSGi (and  
continue to). It's not what I thought it was when I started out; it is  
indeed low-level - much lower level than I anticipated. I do intend to  
move on to using Blueprint but I've inherited this project and it is  
using OSGi at this low level right now. And I've been reading both  
"OSGi In Action" and "Enterprise OSGi In Action".  

I've solved my main problem. The advice that I've been given here was  
well-intentioned but it seemed to be predicated on the idea that the  
code consuming the RepositoryAdmin service was in a bundle, which it was  
not. I'm trying to access a RepositoryAdmin from my non-bundle app  
code. I solved the ClassCastException issue by adding the  
'org.apache.felix.bundlerepository' package to the  
FRAMEWORK_SYSTEMPACKAGES_EXTRA string. I got the idea from here:  
http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html#ApacheFelixFrameworkLaunchingandEmbedding-hostserviceusage.
  

But now I have another problem: the RepositoryAdmin service reference is  
null. I've installed and started the Felix bundle repository bundle.  
I'm not sure what else to do. Any ideas on this one?  

Thanks,  
Tim  

On 08/06/2014 04:33 PM, Paulo Renato de Athaydes wrote:  
> I think he meant the package imports in the MANIFEST file.  
> You need to make sure you are importing the package where RepositoryAdmin is 
> (which should be in an API bundle) with the exact same version in both the 
> consumer bundle of the service and the implementator bundle of the service. 
> Look out for split packages (packages that are exported by more than one 
> bundle, you really don't want that to happen)!!  
> By the way, if you need to depend so much on the osgi API, I would imagine 
> you're doing something really low-level.  
> I have been using OSGi for a long time and I practically never depend on the 
> OSGi API (so my classes are always POJOs) or need to worry about writing 
> MANIFEST files (but I do like to read to make sure BND is doing what I want 
> it to, via either the Maven Bundle Plugin or Gradle's OSGi plugin), 
> publishing/consuming Services manually (which I usually do with Blueprint, 
> but have now switched to IPojo) or anything else related to OSGi other than 
> just declaring which packages I want to Export from each bundle (not Import 
> because that should be done automatically). The chance of error if you manage 
> these things manually is just too big.  
> If you use Maven, have a look at the dependencies of your projects. That's 
> where the Bundle plugin will gather information about which versions of each 
> packages your bundles should import. Don't mess with package imports, let the 
> plugin do its job and then check the MANIFEST to see what you've got (ie. 
> don't explicitly say which packages you will import in the pom.xml)... If you 
> get ClassCastException for classes that are clearly compatible (you may even 
> get something like MyClass cannot be cast to MyClass) you just have some 
> issues with your imports (as already mentioned) for your bundle (not the Java 
> imports!), ie. the bundle which exports the service sees one version of 
> MyClass, the bundle which imports it sees another version of it.  
> Hope this makes you understand how this stuff works. I had to read OSGi in 
> Action (for the low-level details) and also Enterprise OSGi in Action (for 
> the real-world usage) to get my head around OSGi, and now I understand it (I 
> hope!), and I love it... if you keep trying to just google for information 
> about OSGi when something doesn't work you will go down the same path as most 
> people and start hating it because you just couldn't get it.  
>  
> Regards,  
> Renato  
>  
>> Date: Wed, 6 Aug 2014 11:58:52 -0400  
>> From: [email protected]  
>> To: [email protected]  
>> Subject: Re: RepositoryAdmin ClassCastException  
>>  
>> Neil,  
>>  
>> Thanks for your reply. Here are the OSGi/Felix -related imports I have  
>> in the class that contains the code that I included in the original  
>> email (below):  
>>  
>> import org.apache.felix.bundlerepository.Resource;  
>> import org.apache.felix.framework.Felix;  
>> import org.apache.felix.framework.util.FelixConstants;  
>> import org.apache.felix.bundlerepository.RepositoryAdmin;  
>> import org.osgi.framework.Bundle;  
>> import org.osgi.framework.BundleException;  
>> import org.osgi.framework.BundleContext;  
>> import org.osgi.framework.Constants;  
>> import org.osgi.framework.ServiceReference;  
>> import org.osgi.util.tracker.ServiceTracker;  
>>  
>> Regardless of which import I'm using I'm still confused as to how this  
>> discrepancy can exist since I'm requesting an implementation of the  
>> RepositoryAdmin I'm importing.  
>>  
>> Thanks for the tip about how to open the ServiceTracker. We are indeed  
>> using open() without an arg. I was not aware of that gotcha.  
>>  
>> Tim  
>>  
>> On 08/06/2014 11:18 AM, Neil Bartlett wrote:  
>>> Tim, you don’t really need to know anything about classloaders! The 
>>> important part from David’s email was the second paragraph. Make sure you 
>>> import the same package that the provider of the service uses, and you will 
>>> be okay.  
>>>  
>>> By the way, how did you open your ServiceTracker? Did you call open(true)? 
>>> If so, this exposes you to incompatible services and potential classloading 
>>> issues… you should nearly always use open(false) or the no-arg open() 
>>> method, which is equivalent. Then OSGi protects you from seeing service 
>>> instances that are incompatible with your bundle.  
>>>  
>>> Regards,  
>>> Neil  
>>>  
>>>  
>>> On 6 August 2014 at 16:04:32, Tim McIver ([email protected]) wrote:  
>>>  
>>> David,  
>>>  
>>> Thanks for the reply. I figured it had to do with Class loaders but I'm  
>>> at a loss as to how this is happening; I don't know a lot about class  
>>> loaders.  
>>>  
>>> Here's some more detail on my situation: as I said we're using Felix in  
>>> an embedded fashion; we instantiate a Felix object and start it from  
>>> within a JavaFX app (we're using IntelliJ). I suppose this is the  
>>> source of the different classloaders. The reason I'm confused is that  
>>> we have been successfully using a ServiceTracker to get references to  
>>> our plugins without any classloading issues. So how can I fix this? Do  
>>> I need access Felix's classloader and use it to load the  
>>> RepositoryAdmin? Any pointers on how to do this?  
>>>  
>>> Thanks,  
>>> Tim  
>>>  
>>> On 08/06/2014 03:15 AM, David Bosschaert wrote:  
>>>> Hi Tim,  
>>>>  
>>>>> java.lang.ClassCastException:  
>>>>> org.apache.felix.bundlerepository.impl.RepositoryAdminImpl cannot be  
>>>>> cast to org.apache.felix.bundlerepository.RepositoryAdmin  
>>>> This happens when the RepositoryAdmin interface is loaded from a  
>>>> different classloader than where the RepositoryAdminImpl loads it  
>>>> from.  
>>>>  
>>>> You need to check that the bundle that runs your code has an import on  
>>>> the org.apache.felix.bundlerepository package like this:  
>>>> Import-Package: org.apache.felix.bundlerepository;version="[1.0,2)"  
>>>> and is wired to the same bundle where you get the RepositoryAdminImpl 
>>>> from.  
>>>>  
>>>>> By the way, is there javadoc for Felix? I can't seem to find any.  
>>>> If you're looking for documentation on Felix, it might be best to look  
>>>> for general OSGi Framework documentation. You can find information on  
>>>> the Felix Framework in the OSGi Core R5 specs [1] or in one of the  
>>>> many books and web articles about the OSGi framework.  
>>>>  
>>>> For documentation about the Bundle Repository, it might be worth  
>>>> looking at the OSGi R5 Enterprise Specs (also at [1]). Chapter 132  
>>>> describes the OSGi Repository Service. Since version 2.0.x this is now  
>>>> also implemented by Felix OBR so using that gives you a standard API  
>>>> to work with the Repository.  
>>>>  
>>>> Cheers,  
>>>>  
>>>> David  
>>>>  
>>>> [1] http://www.osgi.org/Download/Release5  
>>>>  
>>>> On 5 August 2014 20:38, Tim McIver <[email protected]> wrote:  
>>>>> Hello,  
>>>>>  
>>>>> I'm using Apache Felix in an embedded fashion. I'm attempting to access  
>>>>> my own bundle repository so I install and start the bundle repository  
>>>>> bundle like so:  
>>>>>  
>>>>> // install the Felix OBR bundle  
>>>>> Bundle obrBundle = null;  
>>>>> try {  
>>>>> obrBundle =  
>>>>> m_felix.getBundleContext().installBundle("file:/home/tim/workspace/clojure/lambdaprime/metascrape-ui/lib/org.apache.felix.bundlerepository-2.0.2.jar");
>>>>>   
>>>>> } catch (BundleException e) {  
>>>>> System.err.println("Error installing Felix OBR bundle.");  
>>>>> e.printStackTrace();  
>>>>> }  
>>>>>  
>>>>> // start the Felix OBR bundle  
>>>>> if (obrBundle != null) {  
>>>>> try {  
>>>>> obrBundle.start();  
>>>>> } catch (BundleException e) {  
>>>>> System.err.println("Could not start Felix OBR bundle.");  
>>>>> e.printStackTrace();  
>>>>> }  
>>>>> }  
>>>>>  
>>>>> I have a private method to get a RepositoryAdmin:  
>>>>>  
>>>>> private static RepositoryAdmin getRepositoryAdmin(BundleContext ctx) {  
>>>>> ServiceReference ref =  
>>>>> ctx.getServiceReference(RepositoryAdmin.class.getName());  
>>>>> if (ref != null) {  
>>>>> return (RepositoryAdmin)ctx.getService(ref);  
>>>>> }  
>>>>> return null;  
>>>>> }  
>>>>>  
>>>>> But when this method is called, I get the following exception:  
>>>>>  
>>>>> java.lang.ClassCastException:  
>>>>> org.apache.felix.bundlerepository.impl.RepositoryAdminImpl cannot be  
>>>>> cast to org.apache.felix.bundlerepository.RepositoryAdmin  
>>>>>  
>>>>> I'm using felix.jar from the bin directory of of the 4.4.1 distribution  
>>>>> and using org.apache.felix.bundlerepository-2.0.2.jar for the bundle  
>>>>> repository. Any ideas what my issue is?  
>>>>>  
>>>>> By the way, is there javadoc for Felix? I can't seem to find any.  
>>>>>  
>>>>> Thanks,  
>>>>> Tim  
>>>>>  
>>>>> ---------------------------------------------------------------------  
>>>>> To unsubscribe, e-mail: [email protected]  
>>>>> For additional commands, e-mail: [email protected]  
>>>>>  
>>>> ---------------------------------------------------------------------  
>>>> To unsubscribe, e-mail: [email protected]  
>>>> For additional commands, e-mail: [email protected]  
>>>>  
>>> ---------------------------------------------------------------------  
>>> To unsubscribe, e-mail: [email protected]  
>>> For additional commands, e-mail: [email protected]  
>>>  
>>>  
>>  
>> ---------------------------------------------------------------------  
>> To unsubscribe, e-mail: [email protected]  
>> For additional commands, e-mail: [email protected]  
>>  
>  


---------------------------------------------------------------------  
To unsubscribe, e-mail: [email protected]  
For additional commands, e-mail: [email protected]  

Reply via email to