【问题标题】:Loading Resources with the Context Loader fails with a NullPointerException使用上下文加载器加载资源失败并出现 NullPointerException
【发布时间】:2012-04-12 06:51:42
【问题描述】:

我只是想知道为什么我不能在 Felix OSGi 中使用线程上下文加载器加载资源?我不应该触摸上下文加载器,是我做错了什么还是一个错误?

我有一个带有简单 Activator 的超级简单的捆绑包:

public class Activator implements BundleActivator {
    public void start(BundleContext context) throws Exception {
        System.out.println("Hello World!!");
        String resourcePath = "META-INF/mySuperDuperResource.txt";

        // works
        System.out.println(Activator.class.getClassLoader().getResource(resourcePath));
        // null-pointer exception
        System.out.println(Thread.currentThread().getContextClassLoader().getResource(resourcePath));

    }
    public void stop(BundleContext context) throws Exception {
        System.out.println("Goodbye World!!");
    }
}

现在使用 Activator.class.getClassLoader 使用类加载器加载资源。但不是 Thread.currentThread().getContextClassLoader()。我得到了:

ERROR: Bundle info.gamlor.osgi [26] Unable to get module class path. (java.lang.NullPointerException)
java.lang.NullPointerException
        at org.apache.felix.framework.BundleRevisionImpl.calculateContentPath(BundleRevisionImpl.java:410)
        at org.apache.felix.framework.BundleRevisionImpl.initializeContentPath(BundleRevisionImpl.java:347)
        at org.apache.felix.framework.BundleRevisionImpl.getContentPath(BundleRevisionImpl.java:333)
        at org.apache.felix.framework.BundleRevisionImpl.getResourceLocal(BundleRevisionImpl.java:472)
        at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1432)
        at org.apache.felix.framework.BundleWiringImpl.getResourceByDelegation(BundleWiringImpl.java:1360)
        at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.getResource(BundleWiringImpl.java:2256)
        at info.gamlor.osgi.Activator.start(Activator.java:23)
        at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:641)
        at org.apache.felix.framework.Felix.activateBundle(Felix.java:1977)
        at org.apache.felix.framework.Felix.startBundle(Felix.java:1895)
        at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944)
        ...
org.osgi.framework.BundleException: Activator start error in bundle info.gamlor.osgi [29].
        at org.apache.felix.framework.Felix.activateBundle(Felix.java:2027)
        at org.apache.felix.framework.Felix.startBundle(Felix.java:1895)
        at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:944)
        at org.apache.felix.gogo.command.Basic.start(Basic.java:729)
        ...
Caused by: java.lang.NullPointerException
        at org.apache.felix.framework.BundleRevisionImpl.getResourceLocal(BundleRevisionImpl.java:474)
        at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1432)
        at org.apache.felix.framework.BundleWiringImpl.getResourceByDelegation(BundleWiringImpl.java:1360)
        at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.getResource(BundleWiringImpl.java:2256)
        at info.gamlor.osgi.Activator.start(Activator.java:23)
        at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:641)
        at org.apache.felix.framework.Felix.activateBundle(Felix.java:1977)
        ... 32 more

现在只要设置线程上下文类加载器就可以了:

Thread.currentThread().setContextClassLoader(Activator.class.getClassLoader());

但这有一种骇人听闻的感觉。感觉以后会咬我的。

【问题讨论】:

    标签: osgi classloader apache-felix


    【解决方案1】:

    我不确定为什么会发生这种情况让您感到惊讶。默认情况下,线程的上下文类加载器设置为其父级的类加载器,一开始就设置为系统类加载器。所以,假设你没有做任何特殊的事情,上下文类加载器是系统类加载器,它与你的包的类加载器不同,因此它找不到你的资源。

    我同意设置上下文类加载器有一种 hacky 的感觉,但有些库需要这样做。我会做类似的事情,

    ClassLoader previous = Thread.currentThread().getContextClassLoader();
    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
    badlyBehavedLibraryCall();
    Thread.currentThread().setContextClassLoader(previous);
    

    【讨论】:

    • 我对这个奇怪的异常感到惊讶。如果资源不可见,通常你会得到一个空值。好的,所以我将保留我的类加载器设置。当然在 try-finally 中设置它。
    猜你喜欢
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2019-10-26
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多