0

I have an OSGI bundle which gets to the RESOLVED state, but never reaches the ACTIVE state. When I run my application, this is the stacktrace I am obtaining: http://tny.cz/fa949f16

Afterwards, when I try to start the bundle explicitly through the OSGI console, I get this error:

start 53
gogo: BundleException: The activator rsy.home.mac.sm.schedule.service.win.WinServiceActivator for bundle rsy.home.mac.sm.schedule.service.win is invalid

Notice that in the end of the stacktrace ouput, there's the following message:

!ENTRY org.eclipse.osgi 4 0 2014-03-14 10:52:50.984 !MESSAGE Bundle rsy.home.mac.sm.schedule.service.win_1.0.0 [53] is not active.

Here's the code from WinServiceActivator:

package rsy.home.mac.sm.schedule.service.win;

import java.util.HashMap;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;


public class WinServiceActivator implements BundleActivator {

    private static BundleContext context;

    @Override
    public void start(BundleContext context) throws Exception {

        ServiceActivator.context = context;

        ScheduleService schedServ = new ScheduleService();

        schedServ.setTdMapping(new HashMap<String, String>());
        schedServ.setHtMapping(new HashMap<String, String>());
        schedServ.setDoMapping(new HashMap<String, String>());

        context.registerService(ScheduleService.class.getName(), 
                schedServ, null);
    }

    @Override
    public void stop(BundleContext context) throws Exception {

        context.ungetService(context.getServiceReference(ScheduleService.class.getName()));
        ServiceActivator.context = null;
    }
}

And this is my MANIFEST file:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: SM Schedule Query Service
Bundle-SymbolicName: rsy.home.mac.sm.schedule.service.sm;singleton:=true
Bundle-Version: 1.0.0
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Service-Component: OSGI-INF/sm_schedule_service.xml
Require-Bundle: rsy.home.mac.sm.jaxrs.lib;bundle-version="1.0.0",
 rsy.home.mac.sm.config;bundle-version="0.1.0",
 rsy.home.mac.log,
 rsy.home.mac.sm.model;bundle-version="1.0.0",
 rsy.home.mac.sm.schedule.service;bundle-version="1.0.0",
 rsy.home.mac.sm.sm.scheduletable;bundle-version="1.0.0",
 resources;bundle-version="1.0.0",
 rsy.home.mac.portal.utilities,
 rsy.home.mac.portal.logging;bundle-version="1.0.0",
 org.eclipse.xsd;bundle-version="2.7.0",
 org.eclipse.osgi
Import-Package: org.osgi.service.http;version="1.2.1"
Bundle-ActivationPolicy: lazy
Bundle-Activator: rsy.home.mac.sm.schedule.service.sm.SmServiceActivator
Export-Package: rsy.home.mac.sm.schedule.service.sm

While googling the error "Activator start error, ClassCastException: xxxx cannot be cast to org.osgi.framework.BundleActivator", I found this:

That error is telling you that you have two copies of the BundleActivator class loaded into your VM somehow. The framework is using one and your bundle is using another.

Do you have any other bundles exporting org.osgi.framework? Where is your bundle getting this package from? If you issue the following command in the Felix shell you can see the wiring:

inspect package requirement <bundle-id>

or shortened to:

inspect p r <bundle-id>

Where <bundle-id> is the ID of your bundle, then you should see from where it is getting org.osgi.framework. If it is not the system bundle (org.apache.felix.framework), then you have an issue.

When I executed the given command, I obtained this output:

org.osgi.framework; version="1.7.0" -> org.eclipse.osgi_3.9.0.v20130410-1557 [0]

Do you think this is the reason why the bundle doesn't start? If so, how can I fix this? Following this comment I found on the internet and the comments and answers from people below, I tried to replace this line in the MANIFEST file:

Import-Package: org.osgi.service.http;version="1.2.1"

by this one:

Import-Package: org.osgi.framework

And I get a whole bunch of errors in the code, whose reason given by Eclipse is:

Multiple markers at this line - Access restriction: The type BundleActivator is not accessible due to restriction on required library rsy.home.mac.sm.jaxrs.lib/lib/org.osgi.core-4.2.0.jar - Access restriction: The type BundleListener is not accessible due to restriction on required library rsy.home.mac.sm.jaxrs.lib/lib/org.osgi.core-4.2.0.jar

I would really appreciate some help on this... Thanks!

ccoutinho
  • 3,308
  • 5
  • 39
  • 47
  • It seems to be `WinServiceActivator` it is complaining about, what does that code look like? – greg-449 Mar 14 '14 at 13:49
  • Are you sure that your WinServiceActivator class is correct? Can you put here some code of this class?? – jjmartinez Mar 14 '14 at 13:54
  • 2
    If the activator cannot be cast to BundleActivator then either it does not implement that interface (sounds unlikely) or somehow it's wired up to a different copy than the framework is using. If inspecting the wires does not help, then look at what classes are actually packaged inside your bundle. Perhaps by accident, a copy of BundleActivator is available in the bundle? – Marcel Offermans Mar 14 '14 at 13:57
  • Initial post edited with the WinServiceActivator code! I'm checking your suggestion right now Marcel – ccoutinho Mar 14 '14 at 14:14
  • I think you should assign the Context parameter to the Context Object of your Activator class, not to the ServiceActivator context. Try to change "ServiceActivator.context = context;" for "this.context = context" – jjmartinez Mar 14 '14 at 15:01
  • @marcel how do I check that? I've been unable to find that until now :/ – ccoutinho Mar 14 '14 at 15:59
  • What I mean is, take a look inside your bundle jar. Do you see a BundleActivator class listed in the jar as an entry. Use jar tf yourjar.jar to list the entries on the command line. – Marcel Offermans Mar 15 '14 at 18:29
  • Sorry, but I'm still not sure about what you mean, neither where to find such a jar. So, I exported a jar file with my bundle's contents, and inspected it with tf utility. Is each listed item an entity? All the classes present within my bundle were present (including its Activator class - WinServiceActivator), as well as rest of its content. Isn't this the only thing done by the tf utility? – ccoutinho Mar 17 '14 at 13:01

1 Answers1

2

I had a similar exception some time ago when I tried to get CXF working in an eclipse rcp application. The reason was that I did require bunddle on org.eclipse.osgi. You should avoid that.

Require bundle means that you import all packages of that bundle. The framework bundle (org.eclipse.osgi) exports the OSGi API. Probably another bundle listed in your require bundle list also exports the BundleActivator package. So you get the class from two sources and likely use a different one than the framework itself.

These problems are the reqson why you should avoid require bundle. Espcially try to avoid doing require bundle on org.eclipse.osgi. THis bundle also exports all packages defined in the system exports. So it exports lots of packages and chances are high you run into problems. In my case with cxf I had a similar problem with the jaxb api that is exported by org.eclipse.osgi and also by one of the bundles cxf brings with it.

This article may give you some more details as the problem you observe often surfaces as a uses constraint violation. http://njbartlett.name/2011/02/09/uses-constraints.html

In general if you have the chance use the maven bundle plugin or bndtools to generate the Manifest. Both have good defaults that avoid most of these problems.

Christian Schneider
  • 19,420
  • 2
  • 39
  • 64
  • Thank you so much, I've learned a lot reading your answer and the article you mentioned. I'm pretty sure my problem is somehow related with this, but I think it must be a bit different. When the aforementioned problem arises, the author's bundle can't resolve, and in my case they are resolved, they just can't reach the active state. And I also don't get any message like this: !MESSAGE Package uses conflict: Import-Package: org.apache. activemq; version="5.4.2" I will read more about the tools you mentioned though. I think that's the right way to go! – ccoutinho Mar 17 '14 at 11:01
  • Hi @Christian! Is it possible to start using bnt tools at this stage"? I've been trying to use it to generate the MANIFEST file, but until now I found nothing helpful on the internet :/ – ccoutinho Mar 17 '14 at 15:55
  • I am not experienced in using bnd directly. I build with maven and use the maven bundle plugin. See this for an example: https://github.com/cschneider/Karaf-Tutorial/tree/master/tasklist – Christian Schneider Mar 17 '14 at 18:18
  • About your problem: I think this might still be the same problem described by Neil. The difference is just if you have uses constraints you will fail early. If you do not have them you will fail on the first usage of the class like in your case. – Christian Schneider Mar 17 '14 at 18:20
  • Missunderstood your question about bndtools. I thought about bnd. Bndtools sjould be a good replacement for the eclise pluging perspective if you do not need the eclipse rcp tooling. This might be helpful http://bndtools.org/tutorial.html – Christian Schneider Mar 18 '14 at 06:06
  • I've been struggling with this in the morning, and I figure it out what it was. Turns out that the problem was exactly the one you mentioned: using a Require where I should have used an Import. No need to use bndtools, but it will surely be handy in the future. Thanks for your help, I will mark your answer as correct, because thanks to it I found the error! – ccoutinho Mar 18 '14 at 11:16