【发布时间】:2019-04-22 18:25:13
【问题描述】:
我是 osgi 世界的新手,可能遗漏了一些东西,而且我在为 liferay 公开同一服务的不同版本时遇到了麻烦。
这是我正在尝试做的事情(对不起我的英语):
我写了一个服务,把它打包成一个bundle,并成功地部署在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-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]
(我预期的)。这意味着(对我而言)捆绑包已部署,但没有任何服务被公开。
然后我以这种方式更新了我的 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。由于“缺少”请求的服务版本,它不会出错。
有人可以给我一些关于我做错了什么的提示吗?
提前致谢。
更新 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
。当我部署它时,它似乎没问题(启动并且状态为“活动”),但bundle ___ID___ 说No exported packages
然后我更新了pilot--test-portlet 的build.gradle 设置了正确的依赖版本(8.0.0)。它的清单文件说Import-Package: it.peernetwork.lr.pilot.testservices;version="[8.0,9)。当我部署这个包时它没有启动(状态“已安装”和错误Unresolved requirement: Import-Package: it.peernetwork.lr.pilot.testservices; version="[8.0.0,9.0.0)")
更新 4 -- -- 已解决 非常感谢@Neil。感谢您的提示,我解决了我的问题。正确的建议是this。
显式声明
Import-Package: it.peernetwork.lr.pilot.testservices;version="[7.2,8)",\
*
在pilot--test-services 的bnd.bnd 文件中(自导入,具有合适的版本范围)使osgi 正确导出包并在需要时加载正确的类实例。
完整的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 版本并且运行顺利。所有“服务”包都部署在 osgi 上。部署具有不同依赖版本的 portlet 包总是需要正确的服务。
再次感谢您。
【问题讨论】:
-
你看日志了吗?部署您的 Test-Portlet 时是否有
org.osgi.framework.BundleException? -
嗨@quatax。我在 tomcat 的日志中没有例外(它说包“已启动”),并且 portlet 包在 osgi 上有
Status=ACTIVE(由bundle ___PORTLET_BUNDLE_ID___命令查看)。我不知道我可以检查更多的日志文件...如果还有更多的日志,请告诉我在哪里可以找到它们,以便我查看。 -
这或多或少是一个疯狂的猜测。您更新的 Test-Portlet 的清单对导入的包有什么说明?你能把你的项目上传到某个地方(例如 GitHub)吗?查看整个项目(包括所有 gradle 文件)肯定会有所帮助 - 否则我将不得不继续猜测。
-
我用所需的信息更新了答案。抱歉,我不能公开此代码,因为它是公司财产。我会尝试在这里为您提供您需要的所有信息,但我无法共享整个项目(不知道 java 文件是否与此上下文相关)
-
因为你不能共享整个项目(而且没有人会对确切的代码感兴趣),我建议建立一个MCVE - 它不仅可以轻松共享,而且它是一个隔离手头的确切问题并了解基础知识的好方法。在相关说明中:我认为一个捆绑包依赖于另一个捆绑包的 exact 版本很奇怪。考虑使用语义版本控制并使您的 portlet 依赖于服务的 API。然后部署所需版本的服务。仅在绝对必要时更新主要版本
标签: osgi versioning liferay-7 bnd