【问题标题】:how to detect if running in osgi container如何检测是否在osgi容器中运行
【发布时间】:2011-08-18 06:05:12
【问题描述】:

我有一个 OSGi 包,它也可以在纯 Java 进程中运行。我需要能够判断捆绑包是否已加载到 OSGi 系统中。我怎样才能做到这一点?如果没有 OSGi 标准的方法来做这件事,我将满足于 Eclipse/Equinox 特定的方法。

【问题讨论】:

    标签: java eclipse osgi


    【解决方案1】:

    将 Bundle-Activator 添加到您的 MANIFEST.MF。如果它被实例化,那么您的 JAR 将在 OSGi 容器中运行。

    【讨论】:

    • 在这里投票。有人可以向新手解释为什么吗?
    • 这是一个简单有效的解决方案。在 OSGi 4.2 之前,没有一种方便的方法来内省类加载器来确定它作为包的状态(PackageAdmin.getBundle 是唯一的方法)。
    • 谢谢。括号中的评论是我认为我需要的(可操作的)细节。
    • 好吧,要访问 PackageAdmin,您必须以某种方式为 getService 获取 BundleContext,因此您需要某个地方的 Bundle-Activator。如果您已经在其他一些 JAR 中有一个 Bundle-Activator,那么可以,您可以使用 PackageAdmin.getBundle 来检查任意类。
    • Bundle-Activator 需要实现非 osgi 环境中不存在的 org.osgi.framework.BundleActivator。
    【解决方案2】:

    如果您没有激活器,也可以尝试询问您的捆绑包:

    Bundle b = org.osgi.framework.FrameworkUtil.getBundle(MyClass.this);
    

    如果它返回 null,那么 OSGi 没有加载你的类。

    【讨论】:

    • 这与“getClass().getClassLoader() instanceof org.osgi.framework.BundleReference”方法相比如何?这是否适用于更广泛的 OSGi 版本?
    • 查看实现,它也依赖于 BundleReference 并且可从 OSGi 4.2 上获得(eclipse 3.5.x?)。我会推荐它而不是 instanceof 检查,因为它是 API。
    • 请注意,“instanceof”检查也是 API,因为规范声明包的类加载器必须实现 BundleReference。
    • 如果此代码在非 osgi 运行时中运行,这不会抛出未找到类的异常吗?
    【解决方案3】:

    您可以检查“this.getClass().getClassLoader() instanceof org.osgi.framework.BundleReference”是否为 true,如果您在 R4.2 OSGi 框架中运行,则应该是这样。

    【讨论】:

    • 我在 Eclipse 设置中进行测试,并将 org.eclipse.osgi 作为类加载器包的开头。我决定检查在非 osgi 情况下类加载器的名称是什么(com.sun .... 我忘了,现在我在家)。尽管如此,这使我的测试可以在其他 OSGI 实现中工作它受制于正在使用的其他非 osgi 类加载器实现并将扳手投入工作。
    【解决方案4】:

    对 Richard S. Hall 的改进答案,它不需要 osgi 的编译和运行时依赖项。它还会检查一个类的类加载器是否实现了org.osgi.framework.BundleReference 接口。

    Class<?> classToCheck = this.getClass().getClassLoader().getClass();
    boolean runningOsgi = isOsgiClassLoader(classToCheck);
    ...
    
    boolean isOsgiClassLoader(Class<?> classLoaderClass) {
        Class<?> c = classLoaderClass;
        while (c != null) {
            if (c.getName().equals("org.osgi.framework.BundleReference")) {
                return true;
            }
            for (Class<?> ifc : c.getInterfaces()) {
                if (isOsgiClassLoader(ifc)) {
                    return true;
                }
            }
            c = c.getSuperclass();
        }
        return false;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-26
      • 2015-05-24
      • 1970-01-01
      • 1970-01-01
      • 2012-09-21
      相关资源
      最近更新 更多