【问题标题】:OSGI @Component annotation does not include references required by the base class while extending an existing OSGI serviceOSGI @Component 注解在扩展现有 OSGI 服务时不包括基类所需的引用
【发布时间】:2018-07-15 09:12:41
【问题描述】:

我正在尝试扩展 OSGI 服务。正在扩展的 OSGI 服务包括一些引用和属性。我正在使用新的org.osgi.service.component.annotations 包。 OSGi R6 实现的注释处理器生成的元 XML 不考虑在我正在扩展的 OSGI 服务中所做的引用和属性声明。

Apache Felix Maven SCR 插件很好地处理了这个用例,使用 Felix 注释注释的类也包括基类的引用和属性。

有没有办法让它与官方的 OSGI 注释实现一起工作。我不想回退到 Felix SCR 插件,除非我必须按照他们的官方网站说的那样继续执行 OSGI,这是一个尚未使用 SCR 插件的新项目。

【问题讨论】:

  • 您正在扩展产品服务的服务(默认情况下随 AEM 提供)?或者它是您源代码中的一项服务?
  • 它默认随 AEM 提供
  • 我建议不要扩展它,除非您绝对别无选择,这些服务会随着新版本的变化而变化,并且您不想在 AEM 服务 impl 更改时继续更新您的服务。你介意分享一下它是什么服务吗?

标签: osgi aem apache-felix


【解决方案1】:

由 OSGi R6 实现的注释处理器生成的元 XML 不考虑在我正在扩展的 OSGI 服务中所做的引用和属性声明。

您所期望的行为取决于您用来生成 XML 的构建工具,而不是注释本身。通常,根据父类中的注释生成 XML 并不是一个好主意。这是因为位于构建时的父类可能与位于运行时的父类不同。在这种情况下,生成的注入站点可能在运行时实际上并不存在,从而导致很多问题。事实上,即使类型相同,您也是从子类引用父类的私有详细信息。

除此之外,您可能正在使用基于 bnd 的工具,例如 maven-bundle-pluginbnd-maven-plugin 来生成 XML 文件。为了避免我提到的问题,bnd 不会在组件的父类中搜索注释,但可以使用以下指令在配置中覆盖此行为:

-dsannotations-options: inherit

如果您添加该配置选项,那么您应该会看到您想要的行为,但强烈建议您不要在父类和子类位于不同包中时执行此操作。

【讨论】:

  • 我尝试通过在 maven-bundle-plugin 配置的指令部分添加 <_dsannotations-options>inherit 来传递 dsannotations-options = inherit。我不认为这被传递给 bnd 并且生成的 XML 仍然相同。配置应该不同吗? PS:我已经放弃了延长服务的计划。只想验证这一点并使用 POM 配置更新答案并将其标记为正确。
  • 根据您给出的语法,我假设您使用的是 maven-bundle-plugin。除了看起来不错的结束标签中缺少“_”之外。您使用的是哪个版本的 maven-bundle-plugin?我偶尔会看到正在使用的真正古老的版本,并且此选项仅在 bnd 3.0.0(2015 年 9 月)中添加。
  • 我正在使用 maven-bundle-plugin。版本是3.5.0。
  • 那应该够新了。其他要检查的事情是,当插件运行时,您继承的类文件在构建路径上可用,并且您继承的服务使用标准注释进行注释(不是来自 bnd 或 Felix 的类似注释不要与标准混用)
  • 基类可能正在使用 Felix SCR 注释,因为这是迄今为止为 AEM 设置的标准。
【解决方案2】:

另一个不需要从基类继承注解的选项是在组件本身中重新声明所需的引用:

@Component(
     service = SomeService.class,
     reference = {
         @Reference(
             name = "baseClassField",
             field = "baseClassField",
             service = SomeOtherService.class
         ),
         @Reference(
             name = "otherBaseClassField",
             field = "otherBaseClassField",
             service = YetAnotherService.class,
             cardinality=ReferenceCardinality.MULTIPLE,
             policy=ReferencePolicy.DYNAMIC
         )
     }
)
public class MyServiceImplementation
    extends AbstractSomeServiceBaseImpl
    implements SomeService
{...}

明显的缺点是您显式地硬编码超类的实现细节,这可能比在构建时隐式继承它们更错误。这样,运行时类不仅可以具有与编译时依赖项不同的字段,而且即使在编译时基类发生更改时,您也必须确保更新您的类以反映添加、删除或重命名的字段。

【讨论】:

    【解决方案3】:

    在 maven 中使用可以这样定义:

    <plugins>
        <plugin>
            <groupId>biz.aQute.bnd</groupId>
            <artifactId>bnd-maven-plugin</artifactId>
            <version>3.5.0</version>
            <executions>
                <execution>
                    <id>run-bnd</id>
                    <goals>
                        <goal>bnd-process</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <bnd><![CDATA[-dsannotations-options: inherit]]></bnd>
            </configuration>
        </plugin>
    </plugins>
    

    【讨论】:

      猜你喜欢
      • 2016-08-05
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-20
      • 2018-09-19
      相关资源
      最近更新 更多