翻译:OSGi Module依赖



原文作者:David H Nebinger

原文地址:https://web.liferay.com/web/user.26526/blog/-/blogs/osgi-module-dependencies

译者博客:www.liferayee.com


假设在Liferay DXP平台上开发module的时候,遇见了需要运行环境(runtime)的依赖的时候,该怎么办?

在这片简短的文章中,我会介绍几种方法...

假设你有一个module需要iText(和iText的依赖)作为依赖。这其实和module本身的功能关系不是很大,但是你现在有这个依赖,需要一种方法来使用它。


方法 1 - 放在全局目录下

这种方法最简单也最粗暴。所有在全局类加载器(比如tomcat的lib和lib/ext)中的类可以被所有类访问,包括Liferay OSGi容器。

但是全局的jar有全局的问题。不仅所需要的jar需要在全局目录,所有jar的依赖也需要在全局目录。并且全局类只有一个版本,其他的消费类无法使用不同的版本。


方法 2 - 让OSGi处理


这个是第二简单的方法,但是可能无法使用。如果你在module中声明一个运行环境的依赖,并且OSGi中有一个bundle可以满足依赖的话,module会使用使用这个依赖。

当你确认OSGi中依赖可以被使用的时候,这个方法就可以使用。因为这个方法是利用portal中已有的依赖,或者你之前已经部署到OSGi容器中的依赖(有些jar可能已经包含了OSGi bundle的信息,可以直接部署到容器中)。

例如,假设我们要声明iText依赖,虽然iText应该不会作为bundle已经部署到了OSGi中,所以如果依赖OSGi容器来使用iText很可能会出错的。现在仅是用作举例

使用build.gradle文件来声明运行环境依赖。这段代码是用来声明iText运行环境依赖的


runtime group: 'com.iowagie', name: 'itext', version: '1.4.8'


如果iText(和其依赖)已经成功的部署到OSGi容器中,通过运行环境依赖声明就可以在你自己的module中使用了。如果iText不可用,你的module就不会启动,并且会报错 -- 依赖无法满足。


方法 3 - 制作成一个超级胖子Module


像那些巨型jar一样,巨型module会拥有所有依赖的类直接暴露在module jar中。

使用Gradle和BND很好实现。

在build.gradle中,你应该像方法2中一样声明运行环境依赖。

并且通过在bnd.bnd中包含所需的资源使module成为一个巨型module:

Include-Resource: @itext-1.4.8.jar

在这里引入依赖jar,一般在gradle下来依赖或者浏览maven库的时候都可以看到具体版本。

要注意的是,也需要引入依赖所以依赖的jar。例如,iText2.08依赖于BouncyCasle mail和prov,所以这些依赖也需要添加:

Include-Resource: @itext-2.0.8.jar,@bcmail-138.jar,@bcprov-138.jar

也需要在build.gradle中添加这些依赖,以便gradle引入这些jar。

如果使用zip工具打开module jar包的话,会看见所有依赖的jar会被解压,class文件会被直接放在module jar包中。

方法 4 - 在Module中引入整个jar


最后的方法是在module中引入jar,和巨型module不一样,这个方法将整个jar包含到module jar中

和方法2,3相似的是,也需要在build.gradle中声明运行环境依赖。

引用jar是在bnd.bnd中完成的。

首先需要定义Bundle-ClassPath属性来引入module jar和其余的依赖jar。在下面的例子中,我指定iText jar会包含在module jar中:


Bundle-ClassPath:\
  .,\
  lib/itext.jar

这里我们不使用Include-Resource声明,而是使用-includeresource来-将jar引入到bundle中:

-includeresource:\
  lib/itext.jar=itext-1.4.8.jar

在这里,我们将itext-1.4.8.jar包含到module中,保存为lib/itext.jar。itext-1.4.8是通过Gradle导入的运行环境依赖。

这种语法也支持通配符,可以有效利用build.gradle选择版本的特性。这个例子是用来包含任何版本的commons-lang:

-includeresource:\
  lib/itext.jar=itext-1.4.8.jar,\
  lib/commons-lang.jar=commons-lang=[0-9]*.jar

如果使用压缩软件打开module的jar文件的话,可以看到jar文件会在lib文件夹下。


总结

实际项目中应该使用哪种方法?和Liferay开发一样,因需而异。

全局方法适用于只需要一种版本的jar包并且需要用到大量的依赖的情况。例如,项目中有20个不同的module全部依赖于iText 1.4.8,这样,全局方法就是最好的选择。

第二种方法只用于依赖jar是OSGi bundle的情况。在这种情况下,你可以使用不同的版本,并且不用担心去编辑bnd文件。

第三种和第四种方法是最常用的放法。在上面这些情境下,你的依赖是包含在module中的,OSGi类容器中的类是不会被不同版本的ja“污染”的。并且,module也是不依赖于当前容器环境的,因为module自己已经包含了所有的依赖,运行环境也不需要为module事前准备依赖。

我个人很喜欢使用第四种方法,以为巨型jar在解压缩类的时候,可能会有路径上的交错(例如xml和配置文件)。第四种方法就不会有这样的问题。


希望你喜欢



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值