【问题标题】:How can I detect runtime libraries of an OSGi bundle if it uses classloader?如果 OSGi 包使用类加载器,我如何检测它的运行时库?
【发布时间】:2015-03-01 15:32:00
【问题描述】:

我正在尝试将一个复杂的应用程序(jForexAPi、DDS2)放入 OSGi 包中。我制作了两个带有嵌入式依赖项的包,包括编译时间和运行时(传递)。所以我在 .jar 包中有带有 .class-es 的包。

当我尝试使用时,我得到了 ClassNotFoundException,因为 DDS2 实现在运行时通过其线程的类加载器加载类。有点像这样:

           Class e = Thread.currentThread().getContextClassLoader().loadClass("com.dukascopy.charts.main.DDSChartsControllerImpl");

我有两个问题:

  1. 如何确定 karaf 中线程的父捆绑包?
  2. 如何解决 OSGi 中的运行时类加载等问题?有没有办法允许或发现运行时类加载?

【问题讨论】:

    标签: java runtime osgi classloader karaf


    【解决方案1】:

    如何确定 karaf 中线程的父捆绑包?

    你不能。线程没有父捆绑包。如果您指的是 Thread 上下文类加载器,那么它在 OSGi 中根本没有定义。 TCC 通常是 Java EE 世界中 webapp 的类加载器。但是,在 OSGi 中,它甚至可以为 null 或任何值。永远不要使用它。

    如何解决 OSGi 中的运行时类加载等问题?有没有办法允许或发现运行时类加载?

    你可以做两件事:

    • 参与项目以允许配置将用于加载这些类的类加载器
    • 实施解决方法:分析ClassNotFoundException的stacktrace,找到可以设置线程上下文类加载器的地方

    如果您选择第二个选项,您的代码将类似于以下内容:

    Thread currentThread = Thread.currentThread();
    ClassLoader previousCL = currentThread.getContextClassLoader();
    try {
        currentThread.setContextClassLoader(DDSChartsControllerImpl.class.getClassLoader());
        callNextFunctionOnStacktrace();
    } finally {
        // You should set the original CL back as other technology might use the TCC tricks, too
        currentThread.setContextClassLoader(previousCL);
    }
    

    【讨论】:

    • 感谢您的完整回答。(Koszi!)
    • 如果我在 karaf bin 的类路径中放置一些 .jar-s (jForexAPi, DDS2) 并允许 etc/jre.properties 中的“丢失”包,那么所有线程和包都将能够使用这些软件包。我说的对吗?
    • 您有机会将外部 jar 中的包添加到 system.packages 或引导委托(引导委托是一个选项,但我建议避免这种情况)。我建议您阅读以下内容:spring.io/blog/2009/01/19/exposing-the-boot-classpath-in-osgi。我建议您使用 config.properties 中的 org.osgi.framework.system.packages.extra 设置而不是 jre.properties。 jre.properties 中的设置也包含在 org.osgi.framework.system.packages 中。
    猜你喜欢
    • 2011-08-18
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多