I'm completely new to OSGI framework and I'm trying to test below scenario with two bundle:
Bundle 1:
I have created a OSGI bundle through maven using artifact group org.apache.karaf.archetypes.
In bundle 1 activator class I'm registering a service as below:
public void start(BundleContext context) {
System.out.println("-------------- Starting firstbundle ----------------");
context.registerService(EmployeeService.class, new EmployeeServiceImpl(), null);
}
Content of bundle 1 MANIFEST.MF file:
Manifest-Version: 1.0
Bnd-LastModified: 1594906982858
Build-Jdk: 1.8.0_251
Built-By: 212807091
Bundle-Activator: com.osgi.learn.firstbundle.Activator
Bundle-Description: firstbundle OSGi bundle project.
Bundle-ManifestVersion: 2
Bundle-Name: firstbundle Bundle
Bundle-SymbolicName: firstbundle
Bundle-Version: 0.0.1.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
Export-Package: com.osgi.learn.firstbundle;version="0.0.1.SNAPSHOT";uses
:="org.osgi.framework"
Import-Package: org.osgi.framework;version="[1.7,2)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-2.3.0.201405100607
Bundle 2:
I have created another independent bundle in the same way bundle 1 has been created.
bundle 2 activator class is as below:
public void start(BundleContext context) {
ServiceReference<?> ref = context.getServiceReference(EmployeeService.class);
EmployeeService empService = (EmployeeService) context.getService(ref);
boolean isRegister = empService.register("rohit", "rohit");
if(isRegister){
System.out.println("employee registered successfully");
} else{
System.out.println("employe is already registered");
}
System.out.println("after register employee list: "+empService.getEmployeeList().size());
}
Content of bundle 2 MANIFEST.MF file:
Manifest-Version: 1.0
Bnd-LastModified: 1594907276585
Build-Jdk: 1.8.0_251
Built-By: 212807091
Bundle-Activator: com.osgi.learn.secondbundle.Activator
Bundle-Description: secondbundle OSGi bundle project.
Bundle-ManifestVersion: 2
Bundle-Name: secondbundle Bundle
Bundle-SymbolicName: secondbundle
Bundle-Version: 0.0.1.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
Export-Package: com.osgi.learn.secondbundle;version="0.0.1.SNAPSHOT";use
s:="org.osgi.framework"
Import-Package: com.osgi.learn.service,org.osgi.framework;version="[1.7,
2)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-2.3.0.201405100607
Now i have installed both bundle in OSGI environment and when i am starting both bundle, bundle 1 is started properly while bundle 2 is throwing error as below:
osgi> ss
"Framework is launched."
id State Bundle
0 ACTIVE org.eclipse.osgi_3.11.3.v20170209-1843
1 ACTIVE org.apache.felix.gogo.runtime_0.10.0.v201209301036
2 ACTIVE org.eclipse.equinox.console_1.1.200.v20150929-1405
3 ACTIVE org.apache.felix.gogo.shell_0.10.0.v201212101605
4 ACTIVE org.apache.felix.gogo.command_0.10.0.v201209301215
5 INSTALLED firstbundle_0.0.1.SNAPSHOT
6 INSTALLED secondbundle_0.0.1.SNAPSHOT
osgi> start 5
-------------- Starting firstbundle ----------------
osgi> start 6
gogo: BundleException: Could not resolve module: secondbundle [6]
Unresolved requirement: Import-Package: com.osgi.learn.service
I am having following doubt:
Can you please let me know why bundle 2 is not getting deploy and how can I resolve it.
Does each bundle Activator class object get unique BundleContext object. If so then how if once bundle is registering the class object with context object would be available for another bundle using context object.
Does all the register objects to the OSGI environment is stored at one place which can be retrieved by any bundle deployed using context object or I have to use some other logic.
Your setup seems a bit confused? You're using an ancient version of bnd and the generated manifest does not seem to match expectations. bnd works from a bnd file or a pom manifest section, it is usually best to show these inputs.
1 Unresolved
The error happens because you've not properly exported/imported your packages.
Import-Package Export-Package
firstbundle org.osgi.framework com.osgi.learn.firstbundle
secondbundle com.osgi.learn.service com.osgi.learn.secondbundle
org.osgi.framework
When you start the secondbundle (6) you get the error that the package com.osgi.learn.service is not exported by any bundle, which matches the manifest information.
So you need someone to export the com.osgi.learn.service package.
2/3 Bundle Context & Service Registry
Each bundle has its own unique Bundle Context object. This object has a getBundle() method that returns its unique Bundle object. However, the service registry is shared by all bundles. By registering and getting services through a Bundle specific BundleContext OSGi can do a lot of nice features like cleaning up, security, and more since OSGi knows the bundle that registers or gets the service.
You might want to get some OSGi experience by following the Bndtools OSGi starter guide, there are also lots of videos to show the different stages. This is based on Bndtools but once you got the experience it should not be hard to return to maven. If you still want, that is :-)
When I'm building my project in IntelliJ, I get errors for each of my .bnd files (I have no other types of errors).
I started working on a new project which works without any problems for my colleagues (which are too busy to help me do the setup).
What I've done so far:
- got the code and imported it as a maven project in IntelliJ (no errors)
- clean installed it from terminal (no errors)
- build the project from IntelliJ (425 errors - around 2 per .bnd file)
- I tried disabling the OSGi plugins (dmServerSupport and Spring OSGi)
- I tried disabling the Inspection OSGi profile
- I tried adding the file in the Compiler -> Excludes (still builds it)
What can I do to get rid of all those errors?
My OSGi Manifest (from looks like this:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Goodies
Bundle-SymbolicName: com.....osgi.goodies
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: ...
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: org.osgi.framework;version="1.7.0",
org.osgi.service.component.annotations;version="1.2.0",
org.osgi.service.event;version="1.3.0",
org.osgi.service.packageadmin;version="1.2.0"
For example, I have this .bnd file:
-classpath: target/classes
-dsannotations: *
Include-Resource: README.HTML
Private-Package: com.....pubsub.impl
Export-Package: com.....pubsub
-dsannotations: *
For the file from above, I'm getting the following errors:
Error:osgi: [pubsub] Invalid Manifest header: -classpath, pattern=[A-Za-z0-9][-a-zA-Z0-9_]+
Error:osgi: [pubsub] Invalid Manifest header: -dsannotations, pattern=[A-Za-z0-9][-a-zA-Z0-9_]+
Another example:
-classpath: target/classes
-dsannotations: *
Include-Resource: README.HTML
Private-Package: com.....security.thread.impl
Export-Package: com.....security.thread
Import-Package: oracle.jdbc;version=0,\
*
Building the project containing the .bnd file from above, will result in the following error:
Error:osgi: [security.thread] Exception: java.io.IOException: invalid header field
at java.util.jar.Attributes.read(Attributes.java:406)
at java.util.jar.Manifest.read(Manifest.java:199)
at java.util.jar.Manifest.<init>(Manifest.java:69)
at aQute.bnd.osgi.Builder.build(Builder.java:116)
at org.jetbrains.osgi.jps.build.BndWrapper.doBuild(BndWrapper.java:262)
at org.jetbrains.osgi.jps.build.BndWrapper.build(BndWrapper.java:192)
at org.jetbrains.osgi.jps.build.OsgiBuildSession.doBuild(OsgiBuildSession.java:211)
at org.jetbrains.osgi.jps.build.OsgiBuildSession.build(OsgiBuildSession.java:79)
at org.jetbrains.osgi.jps.build.OsmorcBuilder.build(OsmorcBuilder.java:54)
at org.jetbrains.osgi.jps.build.OsmorcBuilder.build(OsmorcBuilder.java:33)
at org.jetbrains.jps.incremental.IncProjectBuilder.buildTarget(IncProjectBuilder.java:1023)
at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:1004)
at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:1065)
at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:956)
at org.jetbrains.jps.incremental.IncProjectBuilder.access$500(IncProjectBuilder.java:73)
at org.jetbrains.jps.incremental.IncProjectBuilder$BuildParallelizer.lambda$queueTask$0(IncProjectBuilder.java:927)
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.
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.
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.