OSGi:不能直接从存储库中安装多个资源吗?

时间:2019-08-15 13:16:04

标签: java osgi osgi-bundle resolver bnd

您好,谢谢您的阅读,

我目前在将多个资源安装到OSGi框架时遇到问题。我正在使用带有Bndtools插件的Eclipse IDE。

我在RFC 112之后有一个在线OSGi存储库。我已经成功编写了一种可以将所有这些资源解析为List<Resource>的方法。现在可以通过使用List的.get(int)方法获取资源。

我已经编写了一种可以将Resource直接安装到框架中的方法,有关其代码,请参见以下内容:

public void installResource(Resource res) {

    RepositoryContent myRepoContext = (RepositoryContent) res;

    InputStream myInputStream = myRepoContext.getContent();

    try {
        installBundle(myInputStream);
        System.out.println("Installation of " + res.toString() + " SUCCESSFUL.");
    } catch (Exception e) {
        System.out.println("Installation of " + res.toString() + " FAILED.");
        e.printStackTrace();
    }

这使用的是我编写的installBundle(InputStream inputstream方法,如下所示:

public void installBundle(InputStream inputStream) {
    Bundle bundle = null;
    try {
        bundle = context.installBundle(null, inputStream);
        System.out.println("Context installed bundle correctly");

    } catch (BundleException e) {
        System.out.println("Context could not install bundle correctly.");
        e.printStackTrace();
    }

}

现在我要尝试的是在框架中安装多个资源。我确实希望他们处于RESOLVED状态,仅INSTALLED状态就足够了。

当我尝试安装1 Resource时,一切正常:

installResource(resource1);

这是正确的,因为如果我随后在shell中使用lb命令在框架中要求当前安装的捆绑软件/资源,则可以看到捆绑软件处于INSTALLED状态:< / p>

13|Installed  |    1|org.dyamand.test.serialization (0.13.15)|0.13.15

到目前为止,该资源的安装方法正在运行。虽然我以为。当我尝试安装其他资源时,出现了问题。我没有收到任何错误消息或异常。相反,我看到自己打印出的消息像Installation of " + res.toString() + " SUCCESSFUL."。这应该意味着资源已正确安装,因为没有错误或没有任何回退。

但是,当我再次使用lb检查分发包时,第二个资源/分发包不存在。第一个是。已尝试使用许多不同的资源(某些资源处于INSTALLED状态,某些资源处于RESOLVED状态)。 它从未成功,仅安装了第一个资源。

例如,如果我停止框架并使用以下代码重新启动它:

installResource(resource1);
installResource(resource2);

唯一发生的事情是开始安装resource1。

如果之前的资源不在RESOLVEDACTIVE状态下,也许无法安装第二个资源吗?

这是我最初的想法,但事实证明这是错误的。我没有直接从从OSGi存储库中获得的资源进行安装,而是去了Maven Central并获得了3个随机捆绑包及其直接URL。可以在下面的代码中找到该URL,以及如何调用该方法来安装。再次使用installBundle方法:

     installBundle("https://search.maven.org/remotecontent?filepath=org/osgi/org.osgi/3.0.0/org.osgi-3.0.0.jar");
     installBundle("https://search.maven.org/remotecontent?filepath=org/osgi/enroute/examples/microservice/rest-app-jpa/0.0.1/rest-app-jpa-0.0.1.jar");
     installBundle("https://search.maven.org/remotecontent?filepath=org/coindirect/api/1.0.1/api-1.0.1.jar");

当这样启动框架,然后使用lb索取捆绑包时,所有三个捆绑包都以INSTALLED状态显示。请参见下面的lb输出:

 13|Installed  |    1|osgi (3.0.0)|3.0.0
 14|Installed  |    1|rest-app-jpa (0.0.1)|0.0.1
 15|Installed  |    1|https://search.maven.org/remotecontent?filepath=org/coindirect/api/1.0.1/api-1.0.1.jar (0.0.0)|0.0.0

我一直在互联网上寻找导致这种情况发生的原因的解释,所以我在这里向大家提出以下问题:有人知道为什么我不能直接在框架中安装多个资源吗? < / p>

我没有看到直接从URL安装与直接从Resource安装有什么不同,因为它们都可以(至少第一次)。有人已经说过,我可以从其直接URL链接安装所有捆绑软件,可以,但是:我没有从存储库中取出的资源的直接URL链接。我只能使用名称空间为Capability的{​​{1}}访问方法,就像我的方法获取osgi.content一样,以便可以安装资源。

非常感谢您的帮助。谢谢!

1 个答案:

答案 0 :(得分:1)

我假设context.installBundle(null, inputStream)是指this method。如果是这样,则您将null作为捆绑商品的location传递。 The specs并未明确说明如果locationnull会发生什么,但他们确实说

  

每个包都由其位置字符串唯一标识。如果已安装的捆绑包正在使用指定的位置,则installBundle方法必须返回该已安装捆绑包的Bundle对象,而不安装新的捆绑包

所以我的猜测是null是(或某种程度上成为)有效的location,然后在第一个尝试之后的每次尝试都尝试使用相同的location,根据规范不安装捆绑软件。