OSGi:不能直接从存储库安装超过 1 个资源?

OSGi: can't install more than 1 Resource directly from a Repository?

您好,感谢您的阅读,

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

我在 RFC 112 之后有一个在线 OSGi 存储库。我已经成功地编写了一个方法,可以将所有这些资源解析成一个List<Resource>。我现在可以通过使用列表的 .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();
    }

}

现在我要做的是将多个资源安装到我的框架中。我 NOT 希望他们处于 RESOLVED 状态,只 INSTALLED 状态就足够了。

当我尝试安装 1 个资源时,一切正常:

installResource(resource1);

这是正常工作的,因为如果我随后使用 shell 中的 lb 命令在框架中请求当前安装的 bundles/resources,我可以看到包在那里INSTALLED 状态:

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

到目前为止一切顺利,资源的安装方法正在运行。虽然我想。当我尝试安装另一个资源时出现问题。我没有收到任何错误消息或异常。相反,我看到自己打印出 Installation of " + res.toString() + " SUCCESSFUL." 之类的消息。这应该意味着资源已正确安装,因为没有错误或没有返回任何内容。

但是当我使用 lb 再次检查捆绑包时,第二个 resource/bundle 不存在。第一个是。这已在许多不同的资源中进行过尝试(一些处于 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 请求捆绑包时,所有 3 个都显示为 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

我一直在互联网上搜索为什么会发生这种情况,所以我想问大家一个问题:有人知道为什么我不能直接在框架中安装多个资源吗?

我看不出直接从 URL 安装与直接从资源安装有何不同,因为它们都有效(至少是第一次)。有人已经说过我可以从他们的直接 URL link 安装我所有的包,是的,这可以工作但是:我没有直接的 URL link 资源我从我的存储库中取出。我只能像我的方法一样访问带有命名空间 osgi.contentCapability 以获取 InputStream 以便可以安装资源。

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

我假设 context.installBundle(null, inputStream) 指的是 this method. If so, you are passing null as bundle's location. The specs 没有明确说明如果 locationnull 会发生什么,但他们确实说

Every bundle is uniquely identified by its location string. If an installed bundle is using the specified location, the installBundle methods must return the Bundle object for that installed bundle and not install a new bundle.

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