【问题标题】:How to use a property file in an OSGi bundle如何在 OSGi 包中使用属性文件
【发布时间】:2013-08-05 12:35:33
【问题描述】:

在我的应用程序的一个 OSGi 包中,我包含一个名为 ontologymapping.properties 的属性文件。 现在我想读取这个属性文件的内容。 在一些示例代码中,我在包的 start 方法中发现了类似的内容:

public void startObservationAdapter(BundleContext context) {
    String filename = context.getProperty("ontologymapping.properties");
    try {
        File file = new File(filename);
        InputStream in = new FileInputStream(file);
        ontologymapping.load(in);
        in.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

其中ontologymapping 是一个属性实例。 当我运行此代码时,JVM 找不到该文件。 我猜原因是该文件未包含在 BundleContext 中。 我怎样才能做到这一点?或者读取属性文件内容的另一种方法是什么? 该包不是声明性的,它是另一个声明性的 api 包。

【问题讨论】:

标签: java file-io properties osgi


【解决方案1】:

我想你有几根电线交叉了。 context.getProperty(..) 类似于 System.getProperty(...),实际上您可以在上下文中找到大部分 System.getProperties()。因此,在您的情况下,并且您的代码似乎执行此操作,您可以使用 VM -D 命令行选项将文件名放在系统属性中:-Dontologymapping.properties="myfile.properties"。这应该使您的代码工作。

但是......这种类型的代码的问题是您现在有一个需要读取文件系统上的文件的包。区分三种情况:

  1. ontologymapping.properties 是用户特定的且很小
  2. ontologymapping.properties 是特定于用户的并且很大(即,属性对于您的代码来说是一个廉价的 GUI)
  3. ontologymapping.properties 只是程序员存储数据的一种便捷方式

在案例 1 中,您可能希望查看带有 Metatype 的配置管理。这允许您创建具有良好配置 GUI 的应用程序。使用 bnd DS 注释,您可以在 Apache Felix Webconsole 中使用非常少的代码和非常好的 gui。

在情况 2 中,您上面的代码是有效的。您可以考虑添加一个 gogo shell 并创建一个命令,以便人们可以阅读和更新它。

在最后一种情况 #3 中,您应该将属性存储在包中并使用 Myclass.class.getResourceAsStream("/ontology.properties") 读取它。在 bnd(tools) 中,只需 Include-Resource: ontolology.properties,它就会出现在您的包中,可供阅读。

【讨论】:

  • 第三种情况正是我需要的。但是,我不明白您对 bnd(tools) 的意思是什么?你的意思是我必须把Include-Resource: ontologymapping.properties 放在我的 MANIFEST.MF 中吗?
  • bnd(tools):bnd 是一个从“bnd”文件创建清单的库。它用于 Apache Felix Maven 捆绑插件和名为 bndtools 的 Eclipse IDE:bndtools.org 这是迄今为止制作捆绑软件的最佳方式。如果您不想使用 bnd,则必须确保 ontologymapping.properties 文件在您的资源中。通过 maven 或通过您的 jar 命令。
【解决方案2】:

您可以使用 bundle.getResource('mypropfile.properties') 获取属性文件的 URL,其中 bundle 是包含属性文件的文件。根据 URL,您可以获得文件的 inputStream (resourceURL.openStream)。您可以将输入流传递给 properties.load 函数。

如果您不想使用特定于 OSGi 的代码,或者您无法获得包含您可以使用类加载器播放的属性文件的捆绑包的捆绑包对象。想象一下 MyClass 与属性文件在同一个包中。在这种情况下,以下代码 sn-p 也可以:

Properties myProps = new Properties();
InputStream is = null;
try {
  is = MyClass.class.getResourceAsStream("ontologymapping.properties");
  myProps.load(is);
} finally {
  is.close();
}

【讨论】:

  • 谢谢,我更喜欢 OSGi 的方式。当我现在运行它时,他仍然找不到属性文件。我仍然得到一个 NullPointerException。属性文件位于编写此代码的包本身中。我是否必须在某处将文件注册为资源?
  • 没有。您可以使用 bundle.getResource 访问包中的任何文件。在您的代码中,如果您调用 context.getBundle().getResource("ontologymapping.properties") 应该返回一个指向您的属性文件的 URL,并且您应该能够使用该 URL 打开一个 InputStream。如果文件在那里并且您确定上下文指向您的包,您应该尝试使用像“/ontologymapping.properties”这样的斜杠来启动资源路径。如果捆绑包仅处于已安装状态,您也可能会遇到问题,但我不认为这是您的情况。
  • 方法调用context.getBundle().getResource("ontologymapping.properties") 返回null 并且文件在目录中,我尝试使用“/”但也没有用,如何检查context.getBundle()退回我的捆绑包?
  • 我修好了,看我的回答
【解决方案3】:

我修好了。 问题是 ontologymapper.properties 位于定义抽象类的包中。 在那个抽象类中,实现了扩展类的 start 方法,在那个 start 方法中我调用了 context.getBundle()。 这似乎返回了实现类的包,而不是抽象类的包。 因此,通过将属性文件与实现类放在包中解决了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2014-10-02
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2018-02-17
    相关资源
    最近更新 更多