【问题标题】:No access to Bundle Resource/File (OSGi)无法访问捆绑资源/文件 (OSGi)
【发布时间】:2023-03-03 00:22:01
【问题描述】:

目前我正在使用 Jetty 和 Equinox 开发基于 OSGi 的 WebApp(请参阅:http://wiki.eclipse.org/Jetty/Tutorial/EclipseRT-Jetty-Starter-Kit)。 到目前为止一切都很好,但我无法访问我自己的包的某些文件/资源​​。 位置/路径是“configuration/data/config.csv”和“configuration/data/data.zip”。 我已经测试了一切:

context.getBundleContext().getBundle().getEntry("config.csv");
context.getBundleContext().getBundle().getResource("config.csv");
this.getClass().getClassLoader().getResource("config.csv");
context.getBundleContext().getDataFile("config.csv");

当然还有所有可能的路径变体,例如:“configuration/data/config.csv”、“/configuration/data/config.csv”、“\configuration/data/config.csv”、“/config.csv” . 此外,我已将文件夹添加到 OSGi 类路径(在 MANIFEST.MF 中):

Bundle-ClassPath: .,
 configuration/data/

生成的 URL 看起来总是像这样(或 null):“configuration/CBR-Data/config.csv”,当我将它传输到文件对象“D:\configuration\CBR-Data\config.csv”时.

但我真正不明白的是,我的一个 DS 的属性文件已完美加载:
<properties entry="configuration/dsconfig.properties"/>

有人有想法/提示或其他什么吗?我快疯了……

【问题讨论】:

  • 您能否发布代码,获取资源的 URL 以及之后您如何使用它。当您使用 getEntry() 时,您应该将“configuration/data/config.csv”作为参数传递给 getEntry()。生成的 URL 将具有以下格式:bundleentry://20.fwk1235/resource.txt。它似乎不可能具有您发布的格式。所以,有一些事情发生了,你的问题并不清楚。
  • 你说得对,对不起。 URL configURL = context.getBundleContext().getBundle().getEntry("configuration/data/confid.csv"); 的输出是“bundleentry://6.fwk33311724/configuration/data/config.csv”。我尝试通过:File configFile = new File(configURL.getPath()); 将 URL 转换为文件。路径输出configFile.getAbsolutePath(); 比:“D:\configuration\data\config.csv”

标签: file resources osgi bundle


【解决方案1】:

您正在正确地从包中检索资源。我建议熟悉一下 getEntry()、getResource() 和 getDataFile() 之间的区别。

因为方法返回正确的 URL,这意味着资源被正确定位,问题在于你如何阅读它们。

两种使用方式是:

  1. 直接从URL打开InputStream

    URL configURL = context.getBundleContext().getBundle().getEntry("configuration/data/config.csv");
    if (configURL != null) {
        InputStream input = configUrl.openStream();
        try {
            // process your input here or in separate method
        } finally {
            input.close();
        }
    }
   
  1. URL 转换为File。不推荐这种方法,因为它假设 Bundle 被部署为目录(而不是存档)。但是,如果您必须处理需要使用 File 对象的遗留库,这将很有帮助。要转换为文件,您不能使用URL.getPath() 方法,因为 Equinox 有自己的 URL 格式。您应该使用org.eclipse.core.runtime.FileLocator 类来解析为FileFileLocator.getBundleFile(Bundle) 完全符合您的要求。

【讨论】:

  • 好的,谢谢!关于此的一些问题:“我建议熟悉 getEntry()、getResource() 和 getDataFile() 之间的区别”你是否有一些链接/指南/教程描述了这些区别?此外,是否有可能自动将一些目录(例如“configuration/data/”)推送到 osgi-configuration 目录中,就像对“org.eclipse.osgi”所做的那样(“configuration/org.eclipse.osgi/bundles/” XX")? --> 类似“configuration/org.mybundle/data/config.csv”的东西。
  • @Zitzit - 我不知道任何此类指南,我主要依赖于 OSGi API javadoc (osgi.org/javadoc/r4v43),其中详细解释了每种方法的作用。为什么要在 osgi-configuration 目录下推送一些目录(我假设它是 Equinox configuration/ 文件夹)?此文件夹是 Equinox 特有的,因此应限制其使用,否则您将依赖 Equinox。
【解决方案2】:

解决了!!! 感谢 Danail Nachev(见评论),他把我带到了正确的道路上!在搜索“bundleentry://xyz”和“bundleresource://”之后,我发现了这个邮件列表帖子:http://www.mail-archive.com/felix-dev@incubator.apache.org/msg02410.html

所以答案如下(Usging (Equinox) FileLocator):

URL configURL = context.getBundleContext().getBundle().getResource("config.csv");
File configFile = new File(FileLocator.toFileURL(configURL).getPath());

但是(也在那个邮件列表中被问到)如果存在其他不仅适用于 Equinox 的解决方案会很有趣吗?

【讨论】:

  • 如果你投票赞成 Danail Nachev 的答案会更好。此外,与其在您的问题中添加另一个答案来说明解决方案是什么,不如编辑您的原始问题并在问题下方添加解决方案。
  • stackoverflow.com/questions/4538898/… 这是一个很好的例子,说明如何更改您的问题以便更容易找到解决方案。
  • @jfenwick - 我想知道你为什么这么认为。 blog.stackoverflow.com/2011/07/… 明确表示自己回答您的问题是正确的做法。
猜你喜欢
  • 2012-09-05
  • 1970-01-01
  • 2016-03-15
  • 1970-01-01
  • 2014-04-27
  • 1970-01-01
  • 2013-08-27
  • 1970-01-01
  • 2016-01-07
相关资源
最近更新 更多