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!
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.
Related
I'm playing with OSGi framework extension bundles in order to fully understand them.
After looking at the OSGi R6 specification (3.15 and 4.2.4.1) I've sucessfully invoked the "start" method of the ExtensionBundleActivator. Now I'm trying to register a service inside such activator. However, when I trying to consume such service, the reference annotation fails to connect the service.
Here's my code ('ve changed the name of the bundle, but it shouldn't matter):
public class ExtensionBundleActivator implements BundleActivator {
#Override
public void start(BundleContext context) throws Exception {
System.out.println("start extension bundle activator!");
context.registerService(
BundleExample.class.getName(),
new BundleExampleImpl(),
new Hashtable<>(new HashMap<>()));
}
#Override
public void stop(BundleContext context) throws Exception {
//service automatically unregistered
}
}
And here's the manifest of such extension bundle:
Manifest-Version: 1.0
Bnd-LastModified: 1476436248622
Build-Jdk: 1.8.0_91
Built-By: massi
Bundle-ClassPath: .
Bundle-ManifestVersion: 2
Bundle-Name: extensionbundleexample
Bundle-SymbolicName: com.massimobono.microsi.extensionbundleexample
Bundle-Version: 0.0.1.SNAPSHOT
Conditional-Package: com.massimobono.microsi.common.*;
Created-By: Apache Maven Bundle Plugin
ExtensionBundle-Activator: com.massimobono.microsi.bundleexample.imp
l.ExtensionBundleActivator
Fragment-Host: system.bundle; extension:=framework
Provide-Capability: osgi.service;objectClass:List<String>="com.massimobo
no.microsi.bundleexample.BundleExample"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Service-Component: OSGI-INF/com.massimobono.microsi.bundleexample.im
pl.ExtensionBundleExample.xml
Tool: Bnd-3.0.0.201509101326
The consuming bundle (part of the bundle):
#Reference(cardinality=ReferenceCardinality.OPTIONAL)
public BundleExample actualBundleExample;
#Activate
public void activate() {
System.out.println("activating " + this.getClass().getSimpleName() + "with actual bundle set to "+ this.actualBundleExample);
}
My question is: What am I doing wrong? Why the consumer can't detect the registered service of the extension bundle? Or maybe I'm just doing something the framework forbids... in this case is it impossible to provide a service from an extension bundle? How can I interact with the code within the extension bundle (aka accessing something inside the extension bundle itself)?
Here some notes:
I'm using felix as OSGi implementation;
Both "ExtensionBundleExample" and "BundleExample" are loaded inside the auto-process folder of felix (the default one is "bundle" but I tweaked the config.properties to use "corebundles" folder;
The output corretly show "start extension bundle activator!" but when it's time to display the reference of actualBundleExample, the output shows "null";
the optional cardinality of BundleExample is used for testing purposing: I just wanted to invoke the "acivator" method the consumer component has (in order to see the System.out.println console;
from my previous question I understand extension bundles are a niche inside the OSGi framework, but I want to understand them nonetheless: I find the lack of examples on the internet regarding this topic quite annoying;
Thanks for any reply!
The primary purpose of extension bundles is for framework extensions, absolutely not for regular usage. I.e. extension bundles are often tightly coupled to a framework. The reason is that many rules do not count for extension bundles because they are on the "wrong" side of the fence. There are few examples for very good reasons. You should not use them unless you really know what you're doing because most of the OSGi rules do not apply.
That said. My expectation is that the package you use for the BundleExample differs between the extension bundle (comes from the class path) and the DS example exported by some bundle. Since they come from different class loaders OSGi considers them different services because you would get a class loader exception when you tried to use it.
You can solve this by letting the framework export this package.
Just a guess.
I have felix-framework-5.0.1 and I'm trying to start slf4j-api-1.6.0.jar bundle into felix isgi container.
in felix console I'm typing install file:bundle/slf4j-api-1.6.0.jar
I'm getting a message Bundle ID: 42
then I'm trying to start the bundle start 42
I'm getting the message
org.osgi.framework.BundleException: Unable to resolve slf4j.api [42](R 42.0): missing requirement [slf4j.api [42](R 42.0)] osgi.wiring.package; (&(osgi.wiring.p
ackage=org.slf4j.impl)(version>=1.5.5)) Unresolved requirements: [[slf4j.api [42](R 42.0)] osgi.wiring.package; (&(osgi.wiring.package=org.slf4j.impl)(version>=
1.5.5))]
g!
Can any body help me? how can I start slf4j bundle into felix?
slf4j-api needs org.slf4j.impl package. This package is included into every slf4j implementations like slf4j-simple, slf4j-logback, etc.
The implementation bundles need org.slf4j package that comes from the API artifact. There is a cross-reference. This can work only due to the reason that implementations are fragment bundles of the API. When the implementation is installed together with the API, they will have a common classloader and they will be resolved together. Both of their requirements will be satisfied.
In short: You must choose one of the implementations and install that as well. E.g.: slf4j-simple.
You should use the same version of API and implementation to satisfy their "cross requirement".
Your library contains the following 3 packages (link):
org.slf4j
org.slf4j.helpers
org.slf4j.spi
but you have to have an additional library that will contain org.slf4j.impl package.
Also, from manifest file you can see what packages are exported (Export-Package) (they are visible by other bundles) and what packages are imported (Import-Package) (they have to be accessible for the given bundle). Sometimes the given package have to be from bundle with the correct version.
If you cannot find correct bundle maybe this page will help you.
I'm trying to take the first steps in familiarizing myself to OSGI framework.
However, I'm not even able to start the bundle which only exports one package, nothing more.
The error the framework shows sounds ridiculous to me as I read it as 'In order to start your bundle I need to resolve openjsip.service.locationservice package.
But this package comes from my bundle !
Anyway, I think I'm wrong, but I can't grasp the problem, could somebody help me ?
ERROR: Bundle openjsip.locationservice [6] Error starting file:////tmp/locationservice-1.0.0-SNAPSHOT.jar (org.osgi.framework.BundleException: Unresolved constraint in bundle openjsip.locationservice [6]: Unable to resolve 6.0: missing requirement [6.0] osgi.wiring.package; (&(osgi.wiring.package=openjsip.service.locationservice)(version>=1.0.0)))
org.osgi.framework.BundleException: Unresolved constraint in bundle openjsip.locationservice [6]: Unable to resolve 6.0: missing requirement [6.0] osgi.wiring.package; (&(osgi.wiring.package=openjsip.service.locationservice)(version>=1.0.0))
at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3826)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1868)
at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1191)
at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:295)
at java.lang.Thread.run(Thread.java:722)
Here is my MANIFEST.MF:
Manifest-Version: 1.0
Bnd-LastModified: 1348338100498
Build-Jdk: 1.7.0_05
Built-By: devel
Bundle-ManifestVersion: 2
Bundle-Name: locationservice
Bundle-SymbolicName: openjsip.locationservice
Bundle-Version: 1.0.0.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
Export-Package: openjsip.service.locationservice;uses:="javax.sip.header
,javax.sip";version="1.0.0.SNAPSHOT"
Import-Package: javax.sip;version="[1.2,2)",javax.sip.header;version="[1
.2,2)"
Tool: Bnd-1.50.0
The error message doesn't seem to match the MANIFEST.MF you have posted. Is it possible that you have rebuilt it in-between?
The error message says that your bundle imports the package openjsip.service.locationservice, and that import could not be resolved. However according to the manifest you only import javax.sip and javax.sip.header. Therefore this error message could not have come from the bundle manifest posted.
Thanks everybody for help, the issue was really with IDEA configuration, where it creates MANIFEST.MF by itself using facet configuration (which I left empty relying on apache maven plugin). For some reason it ignores this plugin or can't work in pair with it yet.
The resolution was to tell it 'Use predefined MANIFEST.MF from target/classes/META-INF'.
Thanks again.
Situation: Open source OSGI framework SMILA (http://www.eclipse.org/smila/) started as Windows Service with the aid of Apache commons-daemon (http://commons.apache.org/daemon/). Trying to load a DLL via System.loadLibrary() from OSGI bundle while Manifest.mf includes Bundle-NativeCode: path/to/dll.
Environment: Windows Server 2003, Java 1.6
Error: During the invocation of System.loadLibrary() the complete Java process hangs. When the service is stopped System.loadLibrary() finish and code execution goes on until the OSGI framework shut down.
The error doesn’t occur on Windows Server 2008 or if the OSGI framework isn’t started as service.
The DLL itself is stripped down to no functionality for testing. All imports are static and the only depended library is kernel32.ddl.
Could anyone imagine why this is happening and how to fix it?
Manifest containing DLL:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: NTFS Utils Acl Win32 Library
Bundle-SymbolicName: com.eccenca.utils.ntfs.acl.win32
Bundle-Version: 2.2.0
Bundle-Vendor: brox IT-Solutions GmbH
Fragment-Host: com.eccenca.utils.ntfs
Eclipse-PlatformFilter: (& (osgi.os=win32) (osgi.arch=x86))
Bundle-NativeCode: ntfsacl/Release/NtfsAcl.dll
Bundle-RequiredExecutionEnvironment: JavaSE-1.6+
Manifest containing code:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: NTFS Utils Acl
Bundle-SymbolicName: com.eccenca.utils.ntfs
Bundle-Version: 2.2.0
Bundle-Vendor: brox IT-Solutions GmbH
Export-Package: com.eccenca.processing.acl,
com.eccenca.utils.ntfs
Import-Package: org.apache.commons.io;version="1.4.0",
org.apache.commons.lang,
org.apache.commons.logging;version="1.1.1",
org.eclipse.smila.blackboard;version="0.8.0",
org.eclipse.smila.datamodel,
org.eclipse.smila.processing;version="0.8.0",
org.eclipse.smila.processing.pipelets;version="0.8.0",
org.eclipse.smila.utils.config;version="0.8.0",
org.eclipse.smila.utils.service;version="0.8.0",
org.osgi.framework;version="1.4.0"
SMILA-Pipelets: com.eccenca.processing.acl.AccessListConverterPipelet
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Code snipped with System.loadLibrary() invocation:
public class ACLList {
private static final org.apache.commons.logging.Log LOG =
org.apache.commons.logging.LogFactory.getLog(ACLList.class);
static {
try {
LOG.debug("Start loading library");
System.loadLibrary("NtfsAcl");
if (LOG.isInfoEnabled()) {
LOG.info("NTFS ACL library was succesfully loaded");
}
} catch (Throwable e) {
LOG.error(e);
}
}
private ACLList() {
}
public static native ArrayList<ACLEntry> getAccessFor(String path,
String serverName) throws IOException;
}
There are two possible issues with the situation you described; I don't know exactly how Equinox handles native code, so I'll just present them to you both.
Bundle-NativeCode requires at least one parameter
You use a Bundle-NativeCode header that just defines a library, and it seems you use Eclipse-PlatformFilter to specify what that library is intended for. Section 3.10 of the spec shows that you need at least one parameter for the library to be selected.
You can change your Bundle-NativeCode header to read
Bundle-NativeCode: ntfsacl/Release/NtfsAcl.dll;osname=win32
and your bundle will be able to find the right library.
Load only from your own bundle
Judging from your code, it could be possible that you define the library in one bundle, and try to load it in another; that doesn't work, a bundle can only load a library that it contains itself.
I try to package an OSGI bundle using the maven-bundle-plugin (which uses BND).
To run properly the bundle must import a package which is not in the classpath during development (because object references will be passed to the bundle methods as "Class" references).
I do not manage to configure the "Import-Package" declaration in the pom.xml or *.bnd file so that the packe will be included in the OSGI Import-Package part of the MANIFEST. I though
Import-Package: de.foo.bar,*
should do the job, but as de.foo.bar is not in the classpath (or better not declared as an import in the code) it will not be taken to the MANIFEST.
Has anybody an idea how to force the package to be available in the OSGi Import-Package MANIFEST declaration.
Thanks and regards
Klaus
I finally found a solution
Import-Package: de.foo.bar;resolution:=optional,*
will put "de.foo.bar" in the "Import-Package" declaration of the bundle MANIFEST.MF even if the package is not imported by the bundle code.