【问题标题】:OSGi @Activate breaks when method has parameters. Error: activate method not found; Component will fail当方法有参数时,OSGi @Activate 会中断。错误:找不到激活方法;组件将失败
【发布时间】:2018-05-18 04:48:06
【问题描述】:

我正在尝试为我的基于 OSGi 的应用程序实现一个优雅的关闭挂钩。我在捆绑中实现它,因为我无法直接访问启动器源。

这是课程:

/**
 * Shutdown Hook for OSGi
 * Based On: https://stackoverflow.com/a/32216407/5284104
 */
@Component()
public class ShutdownHookActivator{

    @Activate
    public void start(ComponentContext cc, BundleContext bc, Map<String,Object> config) {
        Thread hook = new Thread() {
            @Override
            public void run() {
                System.out.println("Stopping OSGi Framework.");
            try {
                Framework systemBundle = bc.getBundle(0).adapt(Framework.class);
                systemBundle.stop();
                System.out.println("Waiting up to 2s for OSGi shutdown to complete...");
                systemBundle.waitForStop(2000);
            } catch (Exception e) {
                System.err.println("Failed to cleanly shutdown OSGi Framework: " + e.getMessage());
                    e.printStackTrace();
                }
            }
        };

        System.out.println("Installing shutdown hook.");
        Runtime.getRuntime().addShutdownHook(hook);
    }
}

但是每当我启动它时,它都会返回一个错误:

错误:[ShutdownHookActivator(8)] 未找到激活方法 [start]; 组件将失败

但是当我从 start 方法中删除参数时,一切正常。所以现在我很困惑,我已经看到 @Activate 方法具有由 OSGi 框架 (http://enroute.osgi.org/services/org.osgi.service.component.html) 自动注入的参数的示例,而其他的只是空的,所以据我所知,这应该可以工作。 (感觉在 OSGi 中都是靠运气)

通过使用 DS Annotations 并获取 Framework BundleContext 来实现此目的的正确方法是什么?甚至可能吗?

编辑: OSGi 环境: BndTools (aQute Launcher?) Apache Felix SCR 2.0.12(OSGi DS 注释 - 6.0.1) 来源可以看这里:https://github.com/Jafre13/ISS-Product

编辑 2: 自动生成的 ShutdownHookActivator.xml:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0" name="dk.sdu.sso.sred.utils.ShutdownHookActivator" activate="start">
  <implementation class="dk.sdu.sso.sred.utils.ShutdownHookActivator"/>
</scr:component>

清单:

Manifest-Version: 1.0
Bnd-LastModified: 1512410080758
Bundle-ManifestVersion: 2
Bundle-Name: dk.sdu.sso.sred
Bundle-SymbolicName: dk.sdu.sso.sred
Bundle-Version: 0.0.0.201712041754
Created-By: 1.8.0_151 (Oracle Corporation)
Import-Package: javax.security.auth.x500,junit.framework,org.junit,org
 .xml.sax,org.xml.sax.ext,org.xml.sax.helpers
Private-Package: dk.sdu.sso.sred.cmd,dk.sdu.sso.sred.lingpipe,dk.sdu.s
 so.sred.api;version="1.0.0",dk.sdu.sso.sred,com.aliasi.test.unit.xml,
 com.aliasi.test.unit.io,com.aliasi.suffixarray,com.aliasi.test.unit.u
 til,com.aliasi.test.unit.crf,com.aliasi.matrix,com.aliasi.test.unit.s
 entences,com.aliasi.test.unit,com.aliasi.tag,com.aliasi.test.unit.hmm
 ,com.aliasi.chunk,com.aliasi.coref,com.aliasi.spell,com.aliasi.test.u
 nit.chunk,com.aliasi.test.unit.features,com.aliasi.coref.matchers,com
 .aliasi.lm,com.aliasi.test.unit.coref,com.aliasi.cluster,com.aliasi.f
 eatures,com.aliasi.test.unit.symbol,com.aliasi.io,com.aliasi.test.uni
 t.tokenizer,com.aliasi.sentences,com.aliasi.test.unit.coref.matchers,
 com.aliasi.test.unit.spell,com.aliasi.test.unit.corpus,com.aliasi.uti
 l,com.aliasi.dca,com.aliasi.symbol,com.aliasi.test.unit.lm,com.aliasi
 .dict,com.aliasi.test.unit.tag,com.aliasi.corpus,com.aliasi.classify,
 com.aliasi.test.unit.dca,com.aliasi.tokenizer,com.aliasi.test.unit.cl
 assify,com.aliasi.crf,com.aliasi.test.unit.cluster,com.aliasi.stats,c
 om.aliasi.test.unit.stats,com.aliasi.test.unit.dict,com.aliasi.test.u
 nit.matrix,com.aliasi.test.unit.suffixarray,com.aliasi.xml,com.aliasi
 .hmm,dk.sdu.sso.sred.utils,org.apache.felix.service.command,org.osgi.
 framework;version="1.8",org.osgi.service.component;version="1.3"
Provide-Capability: osgi.service;objectClass:List<String>="dk.sdu.sso.
 sred.api.SRedAPI",osgi.service;objectClass:List<String>="dk.sdu.sso.s
 red.cmd.ModelCommands",osgi.service;objectClass:List<String>="dk.sdu.
 sso.sred.cmd.SRedCommands"
Require-Capability: osgi.extender;filter:="(&(osgi.extender=osgi.compo
 nent)(version>=1.3.0)(!(version>=2.0.0)))",osgi.ee;filter:="(&(osgi.e
 e=JavaSE)(version=1.8))"
Service-Component: OSGI-INF/dk.sdu.sso.sred.SRed.xml,OSGI-INF/dk.sdu.s
 so.sred.cmd.ModelCommands.xml,OSGI-INF/dk.sdu.sso.sred.cmd.SRedComman
 ds.xml,OSGI-INF/dk.sdu.sso.sred.utils.ShutdownHookActivator.xml
Tool: Bnd-3.5.0.201709291849

【问题讨论】:

  • 您在构建时使用什么版本的 DS 规范?你在运行时使用什么版本的 scr?
  • @ChristianSchneider DS 规范是 6.0.1。 SCR 运行时为 2.0.12。
  • 这是最新的,所以我不认为旧版本会导致任何问题。也许不是所有的参数都同时支持。

标签: java osgi osgi-bundle


【解决方案1】:

从清单中可以明显看出您的问题发生的原因。您将 OSGi API 作为私有包。这意味着这些类被嵌入到您的 jar 中,因此它们将与框架和 DS 使用的规范类不兼容。

因此,解决方案是确保您仅将私有包用于您真正需要嵌入的内容。永远不要将它用于 OSGi api 包。您需要导入它们才能工作。

【讨论】:

  • 它产生相同的结果。它仍然显示“错误:[ShutdownHookActivator(20)] 未找到激活方法 [start];组件将失败”。在我删除所有参数之前它总是失败,然后它确实可以工作,但是我无法访问 Frameworks BundleContext。
  • 你能发布 Manifest(尤其是导入)和为你的组件生成的 xml(你在 jar 中找到它)吗?
  • 更新了主帖。我在生成 JAR 文件时使用了 start(BundleContext bc)。
  • 克里斯蒂安是对的。您没有导入 OSGi 包:org.osgi.service.component 和 org.osgi.framework。因此 SCR 无法使用您的 activate 方法,因为它没有 ComponentContext 和 BundleContext ,它们的类型与您的包中的私有类型相同。
猜你喜欢
  • 2017-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多