OSGI bundle dependencies - java

I have created an bundle which relies on SLF4J and as such am using Logback for the OSGI implementation. This all bundles up and installs OK but when I come to start the bundle I get the following exception:
org.osgi.framework.BundleException: Unable to resolve com.felix.test
[20](R 20.0): missing requirement [com.felix.test [20](R 20.0)]
osgi.wiring.package; (osgi.wiring.package=groovy.lang) Unresolved
requirements: [[com.felix.test [20](R 20.0)] osgi.wiring.package;
(osgi.wiring.package=groovy.lang)]
I can see in my manifest file groovy.lang is listed in Import-Package and I'm pretty sure the problem is that Logback is being embedded but none of it's references are.
I'm using to create the bundle, here's the config:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.5.4</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Import-Package>
*
</Import-Package>
<Embed-Dependency>
*
</Embed-Dependency>
<Embed-Directory>
osgi-inf/libs
</Embed-Directory>
<Embed-Transitive>
true
</Embed-Transitive>
</instructions>
</configuration>
</plugin>
Here's my manifest:
Manifest-Version: 1.0
Bnd-LastModified: 1436982944102
Build-Jdk: 1.8.0_45
Built-By: tim.clifford
Bundle-ClassPath: .,osgi-inf/libs/org.osgi.core-1.0.0.jar,osgi-inf/libs/
servlet-api-2.5.jar,osgi-inf/libs/org.apache.felix.scr.annotations-1.9.
6.jar,osgi-inf/libs/httpclient-osgi-4.5.jar,osgi-inf/libs/httpclient-4.
5.jar,osgi-inf/libs/httpcore-4.4.1.jar,osgi-inf/libs/commons-logging-1.
2.jar,osgi-inf/libs/commons-codec-1.9.jar,osgi-inf/libs/httpmime-4.5.ja
r,osgi-inf/libs/httpclient-cache-4.5.jar,osgi-inf/libs/fluent-hc-4.5.ja
r,osgi-inf/libs/ehcache-2.10.0.jar,osgi-inf/libs/slf4j-api-1.7.7.jar,os
gi-inf/libs/commons-lang3-3.4.jar,osgi-inf/libs/logback-classic-1.1.3.j
ar,osgi-inf/libs/logback-core-1.1.3.jar
Bundle-ManifestVersion: 2
Bundle-Name: com.felix.test
Bundle-SymbolicName: com.felix.test
Bundle-Version: 1.0.0.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
Embed-Dependency: *
Embed-Directory: osgi-inf/libs
Embed-Transitive: true
Embedded-Artifacts: osgi-inf/libs/org.osgi.core-1.0.0.jar;g="org.apache.
felix";a="org.osgi.core";v="1.0.0",osgi-inf/libs/servlet-api-2.5.jar;g=
"javax.servlet";a="servlet-api";v="2.5",osgi-inf/libs/org.apache.felix.
scr.annotations-1.9.6.jar;g="org.apache.felix";a="org.apache.felix.scr.
annotations";v="1.9.6",osgi-inf/libs/httpclient-osgi-4.5.jar;g="org.apa
che.httpcomponents";a="httpclient-osgi";v="4.5",osgi-inf/libs/httpclien
t-4.5.jar;g="org.apache.httpcomponents";a="httpclient";v="4.5",osgi-inf
/libs/httpcore-4.4.1.jar;g="org.apache.httpcomponents";a="httpcore";v="
4.4.1",osgi-inf/libs/commons-logging-1.2.jar;g="commons-logging";a="com
mons-logging";v="1.2",osgi-inf/libs/commons-codec-1.9.jar;g="commons-co
dec";a="commons-codec";v="1.9",osgi-inf/libs/httpmime-4.5.jar;g="org.ap
ache.httpcomponents";a="httpmime";v="4.5",osgi-inf/libs/httpclient-cach
e-4.5.jar;g="org.apache.httpcomponents";a="httpclient-cache";v="4.5",os
gi-inf/libs/fluent-hc-4.5.jar;g="org.apache.httpcomponents";a="fluent-h
c";v="4.5",osgi-inf/libs/ehcache-2.10.0.jar;g="net.sf.ehcache";a="ehcac
he";v="2.10.0",osgi-inf/libs/slf4j-api-1.7.7.jar;g="org.slf4j";a="slf4j
-api";v="1.7.7",osgi-inf/libs/commons-lang3-3.4.jar;g="org.apache.commo
ns";a="commons-lang3";v="3.4",osgi-inf/libs/logback-classic-1.1.3.jar;g
="ch.qos.logback";a="logback-classic";v="1.1.3",osgi-inf/libs/logback-c
ore-1.1.3.jar;g="ch.qos.logback";a="logback-core";v="1.1.3"
Export-Package: com.felix.test;version="1.0.0"
Import-Package: groovy.lang,javax.crypto,javax.crypto.spec,javax.jms,jav
ax.mail,javax.mail.internet,javax.management,javax.management.openmbean
,javax.naming,javax.naming.directory,javax.naming.ldap,javax.net,javax.
net.ssl,javax.security.auth.x500,javax.sql,javax.swing.event,javax.tran
saction,javax.transaction.xa,javax.xml.datatype,javax.xml.namespace,jav
ax.xml.parsers,javax.xml.stream,javax.xml.stream.events,net.spy.memcach
ed,org.apache.avalon.framework.logger,org.apache.felix.scrplugin,org.ap
ache.felix.scrplugin.annotations,org.apache.felix.scrplugin.description
,org.apache.log,org.apache.log4j,org.codehaus.commons.compiler,org.code
haus.groovy.control,org.codehaus.groovy.control.customizers,org.codehau
s.groovy.reflection,org.codehaus.groovy.runtime,org.codehaus.groovy.run
time.callsite,org.codehaus.groovy.runtime.typehandling,org.codehaus.gro
ovy.runtime.wrappers,org.codehaus.groovy.transform,org.codehaus.janino,
org.hibernate,org.hibernate.cache,org.hibernate.cache.access,org.hibern
ate.cfg,org.hibernate.impl,org.hibernate.stat,org.hibernate.transaction
,org.ietf.jgss,org.osgi.service.cm,org.quartz,org.quartz.impl,org.quart
z.impl.jdbcjobstore,org.quartz.impl.matchers,org.quartz.simpl,org.terra
cotta.quartz,org.terracotta.toolkit,org.terracotta.toolkit.atomic,org.t
erracotta.toolkit.builder,org.terracotta.toolkit.cache,org.terracotta.t
oolkit.cluster,org.terracotta.toolkit.collections,org.terracotta.toolki
t.concurrent.locks,org.terracotta.toolkit.config,org.terracotta.toolkit
.events,org.terracotta.toolkit.feature,org.terracotta.toolkit.internal,
org.terracotta.toolkit.internal.cache,org.terracotta.toolkit.internal.c
luster,org.terracotta.toolkit.internal.collections,org.terracotta.toolk
it.internal.concurrent.locks,org.terracotta.toolkit.internal.feature,or
g.terracotta.toolkit.monitoring,org.terracotta.toolkit.nonstop,org.terr
acotta.toolkit.rejoin,org.terracotta.toolkit.search,org.terracotta.tool
kit.search.attribute,org.terracotta.toolkit.store,org.xml.sax,org.xml.s
ax.helpers,sun.misc,sun.reflect
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.6))"
Tool: Bnd-2.4.1.201501161923
Am I going about it the right way or is there a better method?
Thank you!

To your question "am I going about is the right way", the answer is "definitely not"!
Please, please don't use Embed-Dependency. This simply takes all of the transitive dependency graph (which in your case includes the Groovy language runtime, somehow) and sticks it inside your bundle.
This misses the point of OSGi entirely. Worse, when you develop your next bundle you will have to go through all this again! Eventually you will have tens of bundles, each carrying around a massive, dead weight of embedded dependencies.
As Christian said, stick to the defaults provided by the maven-bundle-plugin. You don't even need to specify <Import-Package>*</Import-Package> since this is already the default. As a result you will get a bundle that has package imports, which is a good thing! But you need to install bundles that provide exports that will match your imports.

You should not embed all dependencies into your bundle. Instead just run with maven bundle plugin defaults. It should create a bundle that you can then deploy into an OSGi container.
I am most experienced with Apache Karaf. There you can just install the bundle using:
install -s mvn:groupId/artifactId/version
In your case this might already work as Apache Karaf comes with pax-logging pre installed.
If you want to use plain felix it is a little more complicated as you will have to gather all dependencies and create a suitable start configuration. In that case bndtools might help.

From the exception you reported in your question I would say none of the bundles in your osgi environment is currently exporting the groovy.lang package.
I would suggest to install the felix gogo shell in your runtime and to issue the following command in the osgi console:
g! inspect cap osgi.wiring.package
This will give you the list of all exported packages in your osgi instance: in this way you can verify whether or not the groovy.lang package is indeed missing.
If this is the case, then you should wrap the groovy-all jar in a bundle as explained here and include it in your running osgi bundles. If you want, you can search a ready-to-use osgi bundle for groovy-all in jpm4j website.

Related

starting slf4j bundle doesn't start on felix

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.

Osgi java.lang.NoClassDefFoundError when trying to retrieve a service from another bundle

So, let's see, I have three bundles: Provider interface, Provider implementation and Client.
Everything is running smoothly on Eclipse, but when I export the bundles and run em, the following error appears when I try to retrieve the Provider Service:
java.lang.NoClassDefFoundError: provider/providerinterface/ProviderService
The interface is exporting his package, so there should be no errors with that. Alongside, Client is also importing the providerInterface package in its manifest.
The .jar of the Provider interface bundle does have the ProviderService class inside, so there are no error exporting either.
Provider Interface's manifest:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: IMA_Provider
Bundle-SymbolicName: IMA_Provider
Bundle-Version: 1.0.0
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: provider.providerinterface
Client's manifest:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MAClient
Bundle-SymbolicName: MA_Client
Bundle-Version: 1.0.0
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: provider.providerinterface,
org.osgi.framework;version="1.3.0",
org.osgi.util.tracker;version="1.4.2"
Provider and Client are just symbolic names, the "Client" bundle imports and uses a lot of other classes from many other bundles with no errors whatsoever. Anyway, I'm getting stuck with this one, and I can't find any reason.
Any help?
Usually there is something wrong with the build.properties file, causing the bundles to miss the actual class files. This does not matter when running directly from Eclipse, but it does matter when you export the bundles using PDE.
Things to check:
Are the classfiles really in the bundles? When checking the bundle, you should have at least at toplevel a provider/ folder and a META-INF/ folder
the build.properties file should look something like:
output.. = bin/
source.. = src/
bin.includes = META-INF/,.
Good luck, Frank
I was finally able to solve this.
There were no issues with the Manifest files or the build.properties, this was a constructor problem.
The MA_Provider implementation was lacking a void constructor; Once I added this
public ProviderImpl(){}
on the implementation class of the ProviderInterface, the OSGi bundles were able to retrieve the service.

OSGI bundle exception, maven dependency issue

I'm pretty new to the OSGI, Felix and Maven stuffs, just started with it.
I'm deploying the java build through jenkins and I get the below dependency issue.
Below is the pom file contents which includes the dependency, I'm not sure whether it is correct, but it still complains about it.
It is looking for "javax.jws" and the version is between 2.0 and 3.0
javax.jws;version>="2.0.0",!javax.jws;version>="3.0.0"
Below is the pom contents.
<Import-Package>!sun.misc,!org.apache.avalon.framework.logger,
!org.ietf.jgss,!org.apache.log,!org.apache.log.format,!org.apache.log.output.io,!com.werken.xpath,!org.apache.tools.ant,!org.apache.tools.ant.taskdefs,
!org.jdom,!org.jdom.input,!org.jdom.output,com.mblox.ngp.sal*;
version="${sal-utils-version}",org.apache.commons.logging;version="1.1",
javax.jws;version>="2.0.0",!javax.jws;version>="3.0.0",
com.sun.xml.ws.api.message,*
</Import-Package>
Below is the exception that I get:
[#|2013-01-29 11:07:44,109|ERROR|NGP-SAL-SALBootstrap-SAL-0|com.mblox.ngp.sal.platform.impl.Sal|172.18.36.38|slodev-rhatf4.mblox.com|sal-1|Unresolved constraint in bundle sap-ws-netcom [24]: Un
able to resolve 24.0: missing requirement [24.0] package; (&(package=javax.jws)(version>=2.0.0)(version>=2.0.0)(!(version>=3.0.0))) - [24.0] package; (&(package=javax.jws)(version>=2.0.0)(versi
on>=2.0.0)(!(version>=3.0.0)))|#]
org.osgi.framework.BundleException: Unresolved constraint in bundle sap-ws-netcom [24]: Unable to resolve 24.0: missing requirement [24.0] package; (&(package=javax.jws)(version>=2.0.0)(version
>=2.0.0)(!(version>=3.0.0))) - [24.0] package; (&(package=javax.jws)(version>=2.0.0)(version>=2.0.0)(!(version>=3.0.0)))
at org.apache.felix.framework.Felix.resolveBundle(Felix.java:3421)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1754)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:905)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:892)
at com.mblox.ngp.sal.platform.impl.Sal.installBundle(Sal.java:608)
at com.mblox.ngp.sal.platform.impl.Sal.getBundle(Sal.java:481)
at com.mblox.ngp.sal.platform.impl.Sal.installSap(Sal.java:630)
at com.mblox.ngp.sal.platform.impl.Sal.initSapBundles(Sal.java:545)
at com.mblox.ngp.sal.platform.impl.Sal.start(Sal.java:290)
at com.mblox.ngp.sal.platform.impl.SALBootstrap.call(SALBootstrap.java:64)
at com.mblox.ngp.sal.platform.impl.SALBootstrap.call(SALBootstrap.java:24)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Any suggestions or pointers to solve this issue.
Is there any bundle which exports the javax.jws package? If not, you can add this Maven dependency to your build and also make sure it is deployed to Felix:
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-ws-metadata_2.0_spec</artifactId>
<version>1.1.2</version>
</dependency>
I also had a problem with javax.jws dependencies using Felix within CQ5 and the solution (strangely) is to explicitly not include javax.jws and javax.jws.soap in the Import-Package part of the bundle manifest. If you're using the maven-bundle-plugin (as I am) you can use the following in the instructions:
<plugin>
<groupid>org.apache.felix</groupid>
<artifactid>maven-bundle-plugin</artifactid>
<version>2.1.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<import-package>!javax.jws,!javax.jws.soap,*</import-package>
</instructions>
</configuration>
</plugin>
I also did not need to have a separate bundle which exports javax.jws and javax.jws.soap. Simply doing the above for my bundle which had the web service client code (generated with wsimport) was enough to make it work.
One other thing, I had to do was to add
sling.bootdelegation.com.sun=com.sun.*
to the sling.properties file.
The CQ5 tutorial on creating webservices mentions it on this page: http://helpx.adobe.com/adobe-cq/using/creating-cq-bundles-consume-web.html
"Note:
This workflow works on Adobe CQ; however, you may encounter the
following exception:
Caused by: java.lang.ClassNotFoundException:
com.sun.xml.internal.ws.spi.ProviderImpl at
org.apache.sling.commons.classloader.impl.ClassLoaderFacade.loadClass(ClassLoaderFacade.java:127)
at java.lang.ClassLoader.loadClass(Unknown Source) at
javax.xml.ws.spi.FactoryFinder.safeLoadClass(Unknown Source) ... 107
more
Solution: To fix this issue and ensure that you can create a
bundle that consumes web services as described in this article, modify
the sling.properties file located in the crx-quickstart\conf folder.
Add the following line of code to this file:
sling.bootdelegation.com.sun=com.sun.*. Then restart the server. Once
you perform this task, you can follow along with this article."
Everything appears to be as expected. You have configured the sap-ws-netcom bundle pom to declare a need for the javax.jws package. And the container is trying to find it while it's trying to resolve the dependency.
org.osgi.framework.BundleException: Unresolved constraint in bundle sap-ws-netcom [24]: Unable to resolve 24.0: missing requirement [24.0] package; (&(package=javax.jws)(version>=2.0.0)(version
>=2.0.0)(!(version>=3.0.0))) - [24.0] package; (&(package=javax.jws)(version>=2.0.0)(version>=2.0.0)(!(version>=3.0.0)))
at org.apache.felix.framework.Felix.resolveBundle(Felix.java:3421)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1754)
The problem is simple, the OSGi container doesn't have javax.jws available, at least not in the versions you are asking for. Did you think that you had made it available?
The way you make it available is by installing a bundle that exports that package. You must do this yourself. This is generally the case with OSGi; if you don't explicitly make the java package available, then it's not there.
If you're running Windows, try putting it in C:\G\ or a shorter path name. it fixed the problem for me!

Unresolved constraint when trying to export a simple interface

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.

Force OSGi package to be imported by maven-bundle-plugin / BND

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.

Categories