osgiversioningliferay-7bnd

OSGi bundle export versioning


I'm pretty new in osgi world, and probably missing something, and i'm having troubles exposing different versions of the same sevice for liferay.

Here is what i am trying to do (and sorry for my english):

I wrote a service, wrapped it in a bundle and successfully deployed it on osgi. My bnd.bnd file looks like this

Bundle-Name: it.peernetwork.lr.pilot.test-services
Bundle-SymbolicName: pilot--test-services
Bundle-Version: 7.1.0
Bundle-Activator: it.peernetwork.lr.pilot.testservices.impl.TestServicesActivator
Export-Package: it.peernetwork.lr.pilot.testservices

and, once packaged, the manifest file is like this

Manifest-Version: 1.0
Bnd-LastModified: 1542646653910
Bundle-Activator: it.peernetwork.lr.pilot.testservices.impl.TestServic
 esActivator
Bundle-ClassPath: .,lib/pn--logger-7.1.0.jar,lib/pn--services-base-7.1
 .0.jar,lib/pn--prop-files-7.1.0.jar,lib/gson-2.8.5.jar,lib/pn--expand
 o-values-7.1.0.jar
Bundle-ManifestVersion: 2
Bundle-Name: it.peernetwork.lr.pilot.test-services
Bundle-SymbolicName: pilot--test-services
Bundle-Version: 7.1.0
Created-By: 1.8.0_191 (Oracle Corporation)
Export-Package: it.peernetwork.lr.pilot.testservices;version="7.1.0"
Import-Package: com.liferay.expando.kernel.exception;version="[1.0,2)"
 ,com.liferay.expando.kernel.model;version="[1.1,2)",com.liferay.expan
 do.kernel.service;version="[1.1,2)",com.liferay.portal.kernel.excepti
 on;version="[7.2,8)",com.liferay.portal.kernel.model;version="[2.0,3)
 ",it.peernetwork.lr.pilot.testservices,org.osgi.framework;version="[1
 .8,2)"
Javac-Debug: on
Javac-Deprecation: off
Javac-Encoding: UTF-8
Private-Package: it.peernetwork.lr.pilot.test.services.impl,it.peernet
 work.lr.pilot.testservices.impl,it.peernetwork.lr.pilot.testservices.
 x,lib,it.peernetwork.lr.logger,it.peernetwork.lr.servicesbase,it.peer
 network.lr.propfiles,it.peernetwork.lr.propfiles.utils,com.google.gso
 n,com.google.gson.annotations,com.google.gson.internal,com.google.gso
 n.internal.bind,com.google.gson.internal.bind.util,com.google.gson.in
 ternal.reflect,com.google.gson.reflect,com.google.gson.stream,it.peer
 network.lr.expandovalues
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-3.2.0.201605172007

This manifest file declares

Export-Package: it.peernetwork.lr.pilot.testservices;version="7.1.0"

and i think this is correct.

Once deployed (successfully) i check the bundle state with the command bundle __BUNDLE_ID__ that gives me

pilot--test-services_7.1.0 [1014]
  Id=1014, Status=ACTIVE      Data Root=/home/ltrioschi/development/liferay-osgi/liferay-ce-portal-7.1.0-ga1/osgi/state/org.eclipse.osgi/1014/data
  "Registered Services"
    {it.peernetwork.lr.pilot.testservices.UselessService}={service.id=1607, service.bundleid=1014, service.scope=singleton}
  No services in use.
  Exported packages
    it.peernetwork.lr.pilot.testservices; version="7.1.0"[exported]
  Imported packages
    com.liferay.expando.kernel.exception; version="1.0.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
    com.liferay.expando.kernel.model; version="1.1.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
    com.liferay.expando.kernel.service; version="1.1.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
    com.liferay.portal.kernel.exception; version="7.2.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
    com.liferay.portal.kernel.model; version="2.0.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
    org.osgi.framework; version="1.8.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
  No fragment bundles
  No required bundles

Then i wrote a portlet that requires this service. The bnd.dnd file is

Bundle-Name: it.peernetwork.lr.pilot.test-portlet
Bundle-SymbolicName: pilot--test-portlet
Bundle-Version: 7.1.0

Import-Package: \
    it.peernetwork.lr.pilot.testservices;version=[7.1.0],\
    *

-metatype: *

And once deployed it loads correctly the service and uses it with no issues.

Now...my problem is i need a new version of the service, but i do not want to undeploy the current version.

So i wrote the new version of the service and the new bnd.bnd file is

Bundle-Name: it.peernetwork.lr.pilot.test-services
Bundle-SymbolicName: pilot--test-services
Bundle-Version: 7.1.1
Bundle-Activator: it.peernetwork.lr.pilot.testservices.impl.TestServicesActivator
Export-Package: it.peernetwork.lr.pilot.testservices

(the only difference is the Bundle-Version)

Once packaged the only difference in manifest file is the Export-Package line

Export-Package: it.peernetwork.lr.pilot.testservices;version="7.1.1"

and looks like it smoothly deploys on osgi

g! lb pilot
START LEVEL 20
   ID|State      |Level|Name
 1014|Active     |   10|it.peernetwork.lr.pilot.test-services (7.1.0)
 1015|Active     |   10|it.peernetwork.lr.pilot.test-services (7.1.1)

but with the command bundle ___NEW_BUNDLE_ID___ i get

No exported packages

instead of

Exported packages
  it.peernetwork.lr.pilot.testservices; version="7.1.1"[exported]

(that i expected). It means (to me) that the bundle is deployed, but none of its services are exposed.

Then i updated my portlets bundle (bnd.bnd) this way

Bundle-Name: it.peernetwork.lr.pilot.test-portlet
Bundle-SymbolicName: pilot--test-portlet
Bundle-Version: 7.1.0

Import-Package: \
    it.peernetwork.lr.pilot.testservices;version=[7.1.1],\
    *

-metatype: *

(changed version in Import-Package) and deployed on osgi. Deploy was correct, but it still uses the old version of the services bundle (7.1.0) even if Import-Package declares version 7.1.1. It does not give error because of the "missing" requested service version.

Can someone give me some tips about what i am doing wrong?

Thanks in advance.


UPDATE 1

Dependencies in build.gradle file have been updated accordingly with the version specified in bnd.bnd.


UPDATE 2

@quatax

The updated portlet bundle's manifest file has Import-Package: it.peernetwork.lr.pilot.testservices;version="[7.1.1]" (followed by all other required imports)...seems correct to me...


UPDATE 3

@Neil Bartlett (Service version updated to 8.0.0)

I updated pilot--test-services bnd.bnd file setting Bundle-Version: 8.0.0. The whole bnd.bnd file is

Bundle-Name: it.peernetwork.lr.pilot.test-services
Bundle-SymbolicName: pilot--test-services
Bundle-Version: 8.0.0
Bundle-Activator: it.peernetwork.lr.pilot.testservices.impl.TestServicesActivator
Export-Package: it.peernetwork.lr.pilot.testservices

Manifest file is

Manifest-Version: 1.0
Bnd-LastModified: 1543316524201
Bundle-Activator: it.peernetwork.lr.pilot.testservices.impl.TestServic
 esActivator
Bundle-ClassPath: .,lib/pn--logger-7.1.0.jar,lib/pn--services-base-7.1
 .0.jar,lib/pn--prop-files-7.1.0.jar,lib/gson-2.8.5.jar,lib/pn--expand
 o-values-7.1.0.jar
Bundle-ManifestVersion: 2
Bundle-Name: it.peernetwork.lr.pilot.test-services
Bundle-SymbolicName: pilot--test-services
Bundle-Version: 8.0.0
Created-By: 1.8.0_191 (Oracle Corporation)
Export-Package: it.peernetwork.lr.pilot.testservices;version="8.0.0"
Import-Package: com.liferay.expando.kernel.exception;version="[1.0,2)"
 ,com.liferay.expando.kernel.model;version="[1.1,2)",com.liferay.expan
 do.kernel.service;version="[1.1,2)",com.liferay.portal.kernel.excepti
 on;version="[7.2,8)",com.liferay.portal.kernel.model;version="[2.0,3)
 ",it.peernetwork.lr.pilot.testservices,org.osgi.framework;version="[1
 .8,2)"
Javac-Debug: on
Javac-Deprecation: off
Javac-Encoding: UTF-8
Private-Package: it.peernetwork.lr.pilot.test.services.impl,it.peernet
 work.lr.pilot.testservices.impl,it.peernetwork.lr.pilot.testservices.
 x,lib,it.peernetwork.lr.logger,it.peernetwork.lr.servicesbase,it.peer
 network.lr.propfiles,it.peernetwork.lr.propfiles.utils,com.google.gso
 n,com.google.gson.annotations,com.google.gson.internal,com.google.gso
 n.internal.bind,com.google.gson.internal.bind.util,com.google.gson.in
 ternal.reflect,com.google.gson.reflect,com.google.gson.stream,it.peer
 network.lr.expandovalues
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-3.2.0.201605172007

. When i deploy it it seems ok (starts and status is "Active"), but bundle ___ID___ says No exported packages

Then i updated pilot--test-portlet's build.gradle setting the correct version of the dependency (8.0.0). It's manifes file says Import-Package: it.peernetwork.lr.pilot.testservices;version="[8.0,9). When i deploy this package it does not start (status "Installed" and error Unresolved requirement: Import-Package: it.peernetwork.lr.pilot.testservices; version="[8.0.0,9.0.0)")


UPDATE 4 -- -- RESOLVED Thank you very much @Neil. Thanks to your tips i solved my issue. The right advice was this.

Explicitally declaring

Import-Package: it.peernetwork.lr.pilot.testservices;version="[7.2,8)",\
        *

in the pilot--test-services's bnd.bnd file (self import, with the opportune version range) makes osgi export correctly the package and loads the correct class instances when required.

The complete bnd.bnd file is

Bundle-Name: it.peernetwork.lr.pilot.test-services
Bundle-SymbolicName: pilot--test-services
Bundle-Version: 7.2.0
Bundle-Activator: it.peernetwork.lr.pilot.testservices.impl.TestServicesActivator
Export-Package: it.peernetwork.lr.pilot.testservices

Import-Package: it.peernetwork.lr.pilot.testservices;version="[7.2,8)",\
        *

In pilot--test-portlet's build.gradle file i only had to update the dependency version

compileOnly group: "it.peernetwork.lr", name: "pilot--test-services", version: "7.2.0"

I tried with version 7.1.0, 7.2.0 and 8.0.0 and works smoothly. All "services" bundles are deployed on osgi. Deploying the portlet bundle with different dependency versions always takes the right service.

Thank you again.


Solution

  • I recommend deleting the Import-Package instruction from your bnd.bnd file for the pilot--test-portlet bundle. It is not necessary: bnd will generate all the imports you need based on the actual requirements in your code.

    Your original bundle pilot--test-services both exports and imports the package it.peernetwork.lr.pilot.testservices. This is correct when your bundle makes use of the package itself in addition to exporting it. Therefore when you install both v7.1.0 and v7.1.1, the v7.1.0 bundle will import the package from the other version instead of exporting the older version. The pilot--test-portlet correctly imports from version 7.1.1.

    In other words, everything here is working the way it should.