felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tim McIver <tmci...@verizon.net>
Subject Re: RepositoryAdmin ClassCastException
Date Thu, 07 Aug 2014 03:23:07 GMT

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:

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?


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: tmciver@verizon.net
>> To: users@felix.apache.org
>> 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 (tmciver@verizon.net) 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 <tmciver@verizon.net> 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: users-unsubscribe@felix.apache.org  
>>>>> For additional commands, e-mail: users-help@felix.apache.org  
>>>> ---------------------------------------------------------------------  
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org  
>>>> For additional commands, e-mail: users-help@felix.apache.org  
>>> ---------------------------------------------------------------------  
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org  
>>> For additional commands, e-mail: users-help@felix.apache.org  
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org

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

View raw message