Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在OSGi模块化包中拆分包的最佳实践是什么?_Java_Jar_Osgi - Fatal编程技术网

Java 在OSGi模块化包中拆分包的最佳实践是什么?

Java 在OSGi模块化包中拆分包的最佳实践是什么?,java,jar,osgi,Java,Jar,Osgi,我想到的用例是fastutil,一个包含数千个特定类型集合实现的大型库。该库在将近500个Maven项目中很受欢迎和使用,但许多用户认为它的大小(>10K类)不可管理,并要求将JAR分成更小的部分。 jar目前是OSGi模块化的,如下所示: Automatic-Module-Name: it.unimi.dsi.fastutil Bundle-Name: it.unimi.dsi.fastutil Bundle-SymbolicName: it.unimi.dsi.fastutil Export

我想到的用例是fastutil,一个包含数千个特定类型集合实现的大型库。该库在将近500个Maven项目中很受欢迎和使用,但许多用户认为它的大小(>10K类)不可管理,并要求将JAR分成更小的部分。

jar目前是OSGi模块化的,如下所示:

Automatic-Module-Name: it.unimi.dsi.fastutil
Bundle-Name: it.unimi.dsi.fastutil
Bundle-SymbolicName: it.unimi.dsi.fastutil
Export-Package: it.unimi.dsi.fastutil.*
Bundle-Version: ${version}
我想把这个罐子分成三部分(为了清楚起见,上面的信息是由一位贡献者创建的,我对OSGi知之甚少)。问题是拆分必然会涉及到拆分包。由于库的性质,无法避免这种情况。我读过很多反对这种做法的文章,但这是我们唯一的选择。我的理解是,在这种情况下,应该使用
Require Bundle
,它允许在Bundle之间拆分包

但是,我还没有找到以前存在的捆绑包的这种做法的示例。在这种情况下,我们希望此修改能够透明地通过用户

想象一下在两个jar中拆分,我目前的理解是使用以下模块化:核心jar将使用

Automatic-Module-Name: it.unimi.dsi.fastutil.core
Bundle-Name: it.unimi.dsi.fastutil.core
Bundle-SymbolicName: it.unimi.dsi.fastutil.core
Export-Package: it.unimi.dsi.fastutil.*
Bundle-Version: ${version}
然后jar的其余部分将模块化为

Automatic-Module-Name: it.unimi.dsi.fastutil
Bundle-Name: it.unimi.dsi.fastutil
Bundle-SymbolicName: it.unimi.dsi.fastutil
Require-Bundle: it.unimi.dsi.fastutil.core
Export-Package: it.unimi.dsi.fastutil.*
Bundle-Version: ${version}
这似乎是合理的,但现在包的一半的bundle名称与另一半的模块名称不同。这会引起问题吗

更一般地说,对于上面的用例(已经是OSGi模块化的jar,需要跨包拆分),最佳实践是什么

更一般地说,对于上面的用例(已经是OSGi模块化的jar,需要跨包拆分),最佳实践是什么

如果您遇到所描述的问题,您没有模块化任何东西。相反地。模块化的目的是创建通过定义良好的接口进行交互的高度内聚的模块。您的提案表明,模块化背后的这一理念没有得到很好的理解

拆分一个大型库是因为它有太多的类,这是模块化中最糟糕的事情。会增加耦合并降低内聚。你做了一些可怕的事情,比如jackson,在你的类路径上你总是需要6个包

对于模块化系统,包装是一个主要的设计方面,这不是你以后可以开始考虑的事情。如果您这样做了,您将无法获得模块化带来的巨大好处,您很可能会一路与OSGi抗争。OSGi是模块化应用程序中最甜美的环境,但对其他应用程序来说,它是个婊子

如果您对模块化很认真,那么您应该尝试以这样一种方式分解包,即每个子包都具有更高的内聚性,并且减少总体耦合。这大大降低了复杂性

有一些技术,比如Tarjan的算法,可以分析代码并找到自然的模块边界。大多数情况下,造成这种混乱的原因是支持其他可选库,但编码方式使它们成为强制性的可传递依赖项。当我需要比较一些陷入困境的公司的类路径时,我总是感到非常难过

尽管如此,但这一点值得怀疑,使用设计良好的服务API通常会使绝大多数类成为私有类,特别是在设计时考虑了配置管理


结论是,如果您在OSGi方面遇到问题,很可能是因为它告诉您没有使用模块化。

正如其他人所说,拆分包是一种不好的做法。关于如何做到这一点,没有最佳实践。这就是说,人们确实需要在某个时候将一个长得太长的包拆分成碎片。我想让你们看看Eclipse,它已经多次这样做了。有关一个示例的讨论,请参见:
org.eclipse.core.runtime
包。我还将注意到,由于过度使用Require Bundle,eclipseide不是使用包导出/导入的最佳实践示例。

我知道的唯一实践是不拆分包。每个包裹都应该来自一个包裹。不清楚你是否对我的答案投了反对票?如果是这样的话,我很乐意提供一个评论。