OSGi 包导出版本控制
OSGi bundle export versioning
我是 osgi 世界的新手,可能遗漏了一些东西,而且我在为 liferay 公开同一服务的不同版本时遇到了麻烦。
这是我正在尝试做的事情(对不起我的英语):
我编写了一个服务,将其打包并成功部署到 osgi 上。我的 bnd.bnd 文件看起来像这样
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
并且,一旦打包,manifest文件是这样的
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
此清单文件声明
Export-Package: it.peernetwork.lr.pilot.testservices;version="7.1.0"
我认为这是正确的。
部署(成功)后,我使用命令 bundle __BUNDLE_ID__
检查捆绑包状态
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
然后我写了一个需要这个服务的 portlet。 bnd.dnd 文件是
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: *
部署后,它会正确加载服务并毫无问题地使用它。
现在...我的问题是我需要一个新版本的服务,但我不想取消部署当前版本。
所以我写了新版本的服务,新的bnd.bnd文件是
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
(唯一的区别是Bundle-Version
)
打包后清单文件中的唯一区别是 Export-Package
行
Export-Package: it.peernetwork.lr.pilot.testservices;version="7.1.1"
看起来它在 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)
但是使用命令 bundle ___NEW_BUNDLE_ID___
我得到
No exported packages
而不是
Exported packages
it.peernetwork.lr.pilot.testservices; version="7.1.1"[exported]
(如我所料)。这意味着(对我而言)捆绑包已部署,但其服务的 none 已公开。
然后我以这种方式更新了我的 portlet 包 (bnd.bnd)
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: *
(在 Import-Package
中更改了版本)并部署在 osgi 上。部署是正确的,但它仍然使用旧版本的服务包 (7.1.0),即使 Import-Package
声明版本 7.1.1。由于 "missing" 请求的服务版本,它不会给出错误。
有人可以告诉我一些关于我做错了什么的提示吗?
提前致谢。
更新 1
build.gradle
文件中的依赖项已相应更新为 bnd.bnd
中指定的版本。
更新 2
@quatax
更新后的 portlet 包的清单文件有 Import-Package: it.peernetwork.lr.pilot.testservices;version="[7.1.1]"
(后跟所有其他必需的导入)...对我来说似乎是正确的...
更新 3
@Neil Bartlett(服务版本更新到8.0.0)
我更新了 pilot--test-services
bnd.bnd 文件设置 Bundle-Version: 8.0.0
。
整个 bnd.bnd 文件是
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-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
。当我部署它时它似乎没问题(启动和状态是 "Active"),但是 bundle ___ID___
说 No exported packages
然后我更新了 pilot--test-portlet
的 build.gradle
设置依赖项的正确版本 (8.0.0)。它的清单文件显示 Import-Package: it.peernetwork.lr.pilot.testservices;version="[8.0,9)
。当我部署这个包时它没有启动(状态 "Installed" 和错误 Unresolved requirement: Import-Package: it.peernetwork.lr.pilot.testservices; version="[8.0.0,9.0.0)"
)
更新 4 -- -- 已解决
非常感谢@Neil。感谢您的提示,我解决了我的问题。正确的建议是 。
明确声明
Import-Package: it.peernetwork.lr.pilot.testservices;version="[7.2,8)",\
*
在 pilot--test-services
的 bnd.bnd
文件中(自导入,具有适当的版本范围)使 osgi 正确导出包并在需要时加载正确的 class 实例。
完整的 bnd.bnd
文件是
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)",\
*
在pilot--test-portlet
的build.gradle
文件中我只需要更新依赖版本
compileOnly group: "it.peernetwork.lr", name: "pilot--test-services", version: "7.2.0"
我尝试了 7.1.0、7.2.0 和 8.0.0 版本,运行顺利。所有 "services" 包都部署在 osgi 上。部署具有不同依赖项版本的 portlet 包始终采用正确的服务。
再次感谢。
我建议从 bnd.bnd
文件中删除 pilot--test-portlet
包的 Import-Package
指令。不是必须的:bnd会根据你代码中的实际需求生成你需要的所有导入。
您的原始包 pilot--test-services
导出和导入包 it.peernetwork.lr.pilot.testservices
。当您的包除了导出包之外还使用包本身时,这是正确的。因此,当您同时安装 v7.1.0 和 v7.1.1 时,v7.1.0 包将从其他版本导入包,而不是导出旧版本。 pilot--test-portlet
从版本 7.1.1 正确导入。
换句话说,这里的一切都在按应有的方式运行。
我是 osgi 世界的新手,可能遗漏了一些东西,而且我在为 liferay 公开同一服务的不同版本时遇到了麻烦。
这是我正在尝试做的事情(对不起我的英语):
我编写了一个服务,将其打包并成功部署到 osgi 上。我的 bnd.bnd 文件看起来像这样
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
并且,一旦打包,manifest文件是这样的
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
此清单文件声明
Export-Package: it.peernetwork.lr.pilot.testservices;version="7.1.0"
我认为这是正确的。
部署(成功)后,我使用命令 bundle __BUNDLE_ID__
检查捆绑包状态
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
然后我写了一个需要这个服务的 portlet。 bnd.dnd 文件是
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: *
部署后,它会正确加载服务并毫无问题地使用它。
现在...我的问题是我需要一个新版本的服务,但我不想取消部署当前版本。
所以我写了新版本的服务,新的bnd.bnd文件是
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
(唯一的区别是Bundle-Version
)
打包后清单文件中的唯一区别是 Export-Package
行
Export-Package: it.peernetwork.lr.pilot.testservices;version="7.1.1"
看起来它在 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)
但是使用命令 bundle ___NEW_BUNDLE_ID___
我得到
No exported packages
而不是
Exported packages
it.peernetwork.lr.pilot.testservices; version="7.1.1"[exported]
(如我所料)。这意味着(对我而言)捆绑包已部署,但其服务的 none 已公开。
然后我以这种方式更新了我的 portlet 包 (bnd.bnd)
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: *
(在 Import-Package
中更改了版本)并部署在 osgi 上。部署是正确的,但它仍然使用旧版本的服务包 (7.1.0),即使 Import-Package
声明版本 7.1.1。由于 "missing" 请求的服务版本,它不会给出错误。
有人可以告诉我一些关于我做错了什么的提示吗?
提前致谢。
更新 1
build.gradle
文件中的依赖项已相应更新为 bnd.bnd
中指定的版本。
更新 2
@quatax
更新后的 portlet 包的清单文件有 Import-Package: it.peernetwork.lr.pilot.testservices;version="[7.1.1]"
(后跟所有其他必需的导入)...对我来说似乎是正确的...
更新 3
@Neil Bartlett(服务版本更新到8.0.0)
我更新了 pilot--test-services
bnd.bnd 文件设置 Bundle-Version: 8.0.0
。
整个 bnd.bnd 文件是
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-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
。当我部署它时它似乎没问题(启动和状态是 "Active"),但是 bundle ___ID___
说 No exported packages
然后我更新了 pilot--test-portlet
的 build.gradle
设置依赖项的正确版本 (8.0.0)。它的清单文件显示 Import-Package: it.peernetwork.lr.pilot.testservices;version="[8.0,9)
。当我部署这个包时它没有启动(状态 "Installed" 和错误 Unresolved requirement: Import-Package: it.peernetwork.lr.pilot.testservices; version="[8.0.0,9.0.0)"
)
更新 4 -- -- 已解决
非常感谢@Neil。感谢您的提示,我解决了我的问题。正确的建议是
明确声明
Import-Package: it.peernetwork.lr.pilot.testservices;version="[7.2,8)",\
*
在 pilot--test-services
的 bnd.bnd
文件中(自导入,具有适当的版本范围)使 osgi 正确导出包并在需要时加载正确的 class 实例。
完整的 bnd.bnd
文件是
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)",\
*
在pilot--test-portlet
的build.gradle
文件中我只需要更新依赖版本
compileOnly group: "it.peernetwork.lr", name: "pilot--test-services", version: "7.2.0"
我尝试了 7.1.0、7.2.0 和 8.0.0 版本,运行顺利。所有 "services" 包都部署在 osgi 上。部署具有不同依赖项版本的 portlet 包始终采用正确的服务。
再次感谢。
我建议从 bnd.bnd
文件中删除 pilot--test-portlet
包的 Import-Package
指令。不是必须的:bnd会根据你代码中的实际需求生成你需要的所有导入。
您的原始包 pilot--test-services
导出和导入包 it.peernetwork.lr.pilot.testservices
。当您的包除了导出包之外还使用包本身时,这是正确的。因此,当您同时安装 v7.1.0 和 v7.1.1 时,v7.1.0 包将从其他版本导入包,而不是导出旧版本。 pilot--test-portlet
从版本 7.1.1 正确导入。
换句话说,这里的一切都在按应有的方式运行。