带有 Felix 的 OSGi 声明式服务 - @Reference 未调用“更新”方法

问题描述 投票:0回答:1

我是第一次学习 OSGi 和声明性服务,无法弄清楚为什么我的

@Reference
字段的“更新”方法没有被调用。我使用的是菲利克斯 7.0.5。我使用 org.apache.felix:maven-bundle-plugin:

使用 Maven 构建了三个捆绑包
  1. osgi.api
    :包含单个界面
    ITask
  2. osgi.taskserviceds
    :包含单个类
    TaskRunnerDs
    @Reference
    字段
  3. osgi.plugin1
    :包含实现
    Plugin1DsTask
    接口的类
    ITask

TaskRunnerDs
中的参考字段显然正在使用
Plugin1DsTask
进行更新,因为我在类中添加了一个执行器来定期检查内容并将其打印出来。但是,我在“更新”属性中指示的方法从未被调用。我找不到任何表明存在问题的内容。我看到的唯一可能的问题是
osgi.plugin1
捆绑包首先启动。然而,我使用
ServiceTracker
完成了同样的练习,这不是问题。我做错了什么?

菲利克斯的输出:

$ java -jar bin/felix.jar
Starting bundle: com.osgi.api
Done starting bundle: com.osgi.api
Starting bundle: com.osgi.plugin1
Done starting bundle: com.osgi.plugin1
Starting bundle: com.osgi.taskserviceds
Done starting bundle: com.osgi.taskserviceds
*** Plugin1DsTask created
*** TaskRunnerDs created
*** TaskRunnerDs activated
____________________________
Welcome to Apache Felix Gogo

g!
*** TaskRunnerDs running - tasks: [com.osgi.plugin1.activator.Plugin1DsTask@bed2ccd]
*** TaskRunnerDs running - tasks: [com.osgi.plugin1.activator.Plugin1DsTask@bed2ccd]
*** TaskRunnerDs running - tasks: [com.osgi.plugin1.activator.Plugin1DsTask@bed2ccd]
*** TaskRunnerDs running - tasks: [com.osgi.plugin1.activator.Plugin1DsTask@bed2ccd]
... <remaining output omitted> ...

g! lb                                                                                                                                       17:39:56

START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (7.0.5)|7.0.5
    1|Active     |    1|jansi (1.18.0)|1.18.0
    2|Active     |    1|JLine Bundle (3.13.2)|3.13.2
    3|Active     |    1|Apache Felix Bundle Repository (2.0.10)|2.0.10
    4|Active     |    1|Apache Felix Gogo Command (1.1.2)|1.1.2
    5|Active     |    1|Apache Felix Gogo JLine Shell (1.1.8)|1.1.8
    6|Active     |    1|Apache Felix Gogo Runtime (1.1.4)|1.1.4
    7|Active     |    1|Apache Felix Declarative Services (2.2.6)|2.2.6
    8|Active     |    1|org.osgi:org.osgi.namespace.extender (1.0.1.201505202024)|1.0.1.201505202024
    9|Active     |    1|org.osgi:org.osgi.service.component (1.5.1.202212101352)|1.5.1.202212101352
   10|Active     |    1|org.osgi:org.osgi.service.component.annotations (1.5.1.202212101352)|1.5.1.202212101352
   11|Active     |    1|org.osgi:org.osgi.util.function (1.0.0.201505202023)|1.0.0.201505202023
   12|Active     |    1|org.osgi:org.osgi.util.promise (1.0.0.201505202023)|1.0.0.201505202023
   13|Active     |    1|osgi.api (1.0.0)|1.0.0
   14|Active     |    1|osgi.plugin1 (1.0.0)|1.0.0
   15|Active     |    1|osgi.taskserviceds (1.0.0)|1.0.0

ITask.java:

package com.osgi.task.api;

import java.util.concurrent.TimeUnit;

public interface ITask extends Runnable {

    String getName();

    int getInterval();

    TimeUnit getIntervalUnit();
}

TaskRunnerDs.java

package com.osgi.taskservice.ds;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;

import com.osgi.task.api.ITask;

@Component
public class TaskRunnerDs {

    @Reference(updated = "updatedTasks", policy = ReferencePolicy.DYNAMIC, cardinality = ReferenceCardinality.AT_LEAST_ONE)
    public volatile List<ITask> fTasks;

    public TaskRunnerDs() {
        System.out.println("*** TaskRunnerDs created");

        // for debugging
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        service.scheduleWithFixedDelay(() -> System.out.println("*** TaskRunnerDs running - tasks: " + fTasks),
                                       1,
                                       1,
                                       TimeUnit.SECONDS);
    }

    @Activate
    public void activate() {
        System.out.println("*** TaskRunnerDs activated");
    }

    public void updatedTasks() {
        System.out.println("*** Change detected to task list - new list:");
        for (ITask task : fTasks) {
            System.out.println("Task: " + task.getName() + " - " + task.getInterval() + " " + task.getIntervalUnit());
        }
    }
}

Plugin1DsTask.java:

package com.osgi.plugin1.activator;

import java.util.concurrent.TimeUnit;
import org.osgi.service.component.annotations.Component;
import com.osgi.task.api.ITask;

@Component
public final class Plugin1DsTask implements ITask {

    public Plugin1DsTask() {
        System.out.println("*** Plugin1DsTask created");
    }

    @Override
    public String getName() {
        return getClass().getSimpleName();
    }

    @Override
    public int getInterval() {
        return 2;
    }

    @Override
    public TimeUnit getIntervalUnit() {
        return TimeUnit.SECONDS;
    }

    @Override
    public void run() {
        System.out.println("Running task: " + getName());
    }
}
java osgi apache-felix declarative-services
1个回答
0
投票

看起来这可能是 Apache Felix DS 中的一个错误。您应该提交错误。

您对

@Reference
的使用是一个“混合”用例,因为它使用字段注入进行绑定/解除绑定,但使用方法注入进行更新。 Felix DS 可能没有正确处理此用例。

© www.soinside.com 2019 - 2024. All rights reserved.