elasticsearch 使用OSGi捆绑包时,java.util.ServiceConfigurationError提供程序不是子类型,elasticsearch,liferay,osgi,osgi-bundle,embedded-osgi,elasticsearch,Liferay,Osgi,Osgi Bundle,Embedded Osgi" /> elasticsearch 使用OSGi捆绑包时,java.util.ServiceConfigurationError提供程序不是子类型,elasticsearch,liferay,osgi,osgi-bundle,embedded-osgi,elasticsearch,Liferay,Osgi,Osgi Bundle,Embedded Osgi" />

elasticsearch 使用OSGi捆绑包时,java.util.ServiceConfigurationError提供程序不是子类型

elasticsearch 使用OSGi捆绑包时,java.util.ServiceConfigurationError提供程序不是子类型,elasticsearch,liferay,osgi,osgi-bundle,embedded-osgi,elasticsearch,Liferay,Osgi,Osgi Bundle,Embedded Osgi,我正在创建一个Liferay 7.1 OSGi包,其中包含一些外部依赖项。考虑到时间,我们选择将外部JAR嵌入到我们的OSGi包中。我已经设法创建了一个bnd文件,其中包括所有ElasticSearch依赖项,并将它们放在bundle类路径上。我使用了github()和bnd.bnd文件中的源代码来检查导入的内容 激活捆绑包时,会引发异常: The activate method has thrown an exception java.util.ServiceConfigurationErr

我正在创建一个Liferay 7.1 OSGi包,其中包含一些外部依赖项。考虑到时间,我们选择将外部JAR嵌入到我们的OSGi包中。我已经设法创建了一个bnd文件,其中包括所有ElasticSearch依赖项,并将它们放在bundle类路径上。我使用了github()和bnd.bnd文件中的源代码来检查导入的内容

激活捆绑包时,会引发异常:

The activate method has thrown an exception 
java.util.ServiceConfigurationError: org.elasticsearch.common.xcontent.XContentBuilderExtension: Provider org.elasticsearch.common.xcontent.XContentElasticsearchExtension not a subtype
    at java.util.ServiceLoader.fail(ServiceLoader.java:239)
    at java.util.ServiceLoader.access$300(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at org.elasticsearch.common.xcontent.XContentBuilder.<clinit>(XContentBuilder.java:118)
    at org.elasticsearch.common.settings.Setting.arrayToParsableString(Setting.java:1257)
activate方法引发了异常
java.util.ServiceConfigurationError:org.elasticsearch.common.xcontent.XContentBuilderExtension:Provider org.elasticsearch.common.xcontent.xContentLasticSearchExtension不是子类型
在java.util.ServiceLoader.fail处(ServiceLoader.java:239)
在java.util.ServiceLoader.access$300(ServiceLoader.java:185)
位于java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376)
位于java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
位于java.util.ServiceLoader$1.next(ServiceLoader.java:480)
位于org.elasticsearch.common.xcontent.XContentBuilder。(XContentBuilder.java:118)
位于org.elasticsearch.common.settings.Setting.arrayToParsableString(Setting.java:1257)
XContentBuilderExtension来自elasticsearch-x-content-6.5.0.jar, ExcontentelasticSearchExtension类包含在elasticsearch-6.5.0.jar中。两者都包含在资源中,并已放在类路径上

Activate方法在我的另一个jar中初始化TransportClient,因此它在激活时发生;)

编辑:

我注意到,在第一次安装或门户重新启动时,不会发生此错误。因此,只有在卸载并重新安装捆绑包时才会发生这种情况。(这是我真正喜欢的功能!)。也许是个愚蠢的想法。。但是否有某种“悬念”?捆绑包未正确安装,或者TransportClient仍然处于活动状态?我正在查这个。欢迎任何提示

编辑2:


我担心这是SPI和OSGi之间的不兼容?我已经检查过了:高级Rest客户机也有同样的问题。(但后来又加了一个扩展名)。我将尝试低级别Rest客户端。我猜这应该是可行的,因为有最小的依赖关系。我仍然很好奇为什么会有不兼容。我当然不是OSGi方面的专家,也不是SPI方面的专家。(是时候学习新东西了!)

在一个Java应用程序中可以有两个弹性搜索连接,Liferay默认情况下不会公开它所拥有的连接

解决方法之一是重建Liferay ES连接器。这没什么大不了的,因为您不需要更改代码,只需更改OSGi描述符即可公开更多服务

我在一个POC项目中做到了这一点,效果很好。棘手的事情是重建Liferay jar,但Pettry通过他类似谷歌的搜索博客帖子解释了这一点。(这是一个系列,但很难在新的Liferay博客中导航,但谷歌可能会有所帮助)不管怎样,这里都有很好的文档记录


唯一需要做的就是在导出部分的bnd.bnd文件中添加
org.elasticsearch.*
。然后,您将能够使用本机弹性API。

似乎是这样一种情况,OSGi使用您的捆绑包解决来自另一个捆绑包的依赖关系,可能是在系统启动时使用您的捆绑包解决包的依赖关系

查看症状:引导或重新启动时不会发生。而且它不是一个子类型

当OSGi使用该捆绑包解决依赖关系时,它将保留一个副本,即使您将其删除。当bundle返回时,以前由另一个bundle使用的包可能仍然存在,您可能会遇到这样的情况:使用的类有两个版本,来自不同的类装入器,这意味着它们不是同一个类,因此不是子类型

仅暴露必要的,以尽量减少此操作的影响。仅在需要导入时导入。如果您正在使用Liferay Gradle配置将包包含在内,请停止—这是一种糟糕的包含方式,因为它会暴露很多内容。如果使用bnd文件包含资源并为adicional类路径位置创建条目,则不必公开。如果有多个bundle使用一个作为依赖项,请确保它们使用的版本,如果exchange对象来自有问题的类,则需要格外小心


PS:您可以在导出和/或导入时包含属性,以便更加具体并避免使用来自错误来源的包。

问题:为什么要将代码嵌入到您自己的包中,而liferay中已经提供了这些包?请参阅,因为我的外部依赖性本机使用ElasticSearch。Liferay不导出弹性包。弹性软件包无法通过OSGi获得。但如果我错了,请纠正我。:)我不是osgi大师,但为什么不使用现有的portal-search-elasticsearch6-impl捆绑包,制作一个副本,更改bdn.bdn并导出所需内容,为其提供一个新版本并部署jar?嗯,这正是我不愿意做的。触摸Liferay的内部束以修复我的。这是一种非常糟糕的做法,我建议你永远不要这样做。在您的情况下,无论何时更新包,都应该手动更新类。除了弹性依赖之外,我们的bundle与现有的portal-search-elasticsearch6-impl没有任何相似之处。OSGi的全部要点是bundle有自己的类路径,甚至可以部署同一依赖的多个版本。我不会将现有的捆绑包滥用为我自己的捆绑包……好的,Kornelito,很明显,这与Daniele Baggio在评论部分给出的答案几乎相同。我知道这是可能的,但我更愿意在自己的代码中保留更改。我不愿意重建默认的生命