【问题标题】:OSGi annotations (Activate, Reference, Component) in ScalaScala 中的 OSGi 注释(激活、引用、组件)
【发布时间】:2020-02-04 20:11:09
【问题描述】:

我正在尝试用 Scala 编写一个 OSGi 服务(大多数其他服务/捆绑包都是用 Java 编写的),但我在语法上有点挣扎。

通常在 Java 中,可以像这样在构造函数上使用 @Activate 注释:

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;

@Component(configurationPid = "PID", service=AgentService.class, immediate=true)
public class AgentServiceImpl implements AgentService {
   @Activate
    public AgentServiceImpl(@Reference Service1 service1, @Reference Service2 service2) {
  // ...
}

在 Scala 中它应该看起来像这样:

import org.osgi.service.component.annotations.{Activate, Component, Deactivate, Reference}

@Component(
  configurationPid = "PID",
  service = Array(classOf[AgentService]),
  immediate = true)
class AgentServiceImpl @Activate() (@Reference service1: Service1, 
                                    @Reference service2: Service2) implements AgentService {
   // ...
}

当我尝试编译这个 Scala 代码(使用 gradle)时,我收到以下错误消息:

error  : In component xxx.xxxx.xx.xx.agent.AgentServiceImpl , multiple references with the same name: service1. Previous def: xxx.xxxx.xx.xx.service.Service1, this def:
error  : In component xxx.xxxx.xx.xx.agent.AgentServiceImpl , multiple references with the same name: service2. Previous def: xxx.xxxx.xx.xx.service.Service2, this def:

这是因为我关于注释的语法错误吗? 我对这个@Activate() 位特别不太确定。在 Java 中我不需要在这里使用方括号 - 但在 Scala 中它不会编译。

有人知道尝试做类似事情的示例项目吗?

【问题讨论】:

  • 我不是 Scala 专家,但 Scalac 是否有可能从具有 Activate 注释的源代码中发射方法?类文件中的javap 显示什么?
  • 当我在类文件上使用javap 时,Service1/Service2 只出现在AgentServiceImpl 的构造函数中。不过,我不太确定我会用这些信息做什么。有什么问题吗?

标签: scala osgi apache-felix


【解决方案1】:

我找到了解决办法:

在构造函数参数前加上val后编译成功:

import org.osgi.service.component.annotations.{Activate, Component, Deactivate, Reference}

@Component(
  configurationPid = "PID",
  service = Array(classOf[AgentService]),
  immediate = true)
class AgentServiceImpl @Activate() (@Reference val service1: Service1, 
                                    @Reference val service2: Service2) implements AgentService {
   // ...
}

这可能是因为OSGi无法正确处理service1service2自动生成的setter方法。

【讨论】:

  • 问题可能是 scalac 生成了带有 Activate 注释的 setter 方法。这就是为什么我建议使用 javap 来检查生成的方法,看看它们是否也用 Activate 注释进行了修饰。
  • 嗯,奇怪,我用javap的时候没看到,但你可能是对的:)
猜你喜欢
  • 2019-08-31
  • 2019-05-08
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 2011-05-22
  • 2023-03-08
  • 1970-01-01
相关资源
最近更新 更多