使用上下文加载器加载资源失败,并显示NullPointerException [英] Loading Resources with the Context Loader fails with a NullPointerException

查看:157
本文介绍了使用上下文加载器加载资源失败,并显示NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm just wondering why I cannot load a resource with the Thread context loader in Felix OSGi? Am I not supposed to touch the context loader, am I doing something wrong or is it a bug?

我有一个带有简单激活器的超级简单捆绑包:

I've a super simple bundle with a simple 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()一起使用.我到了:

Now loading the resource with with the class loader with the Activator.class.getClassLoader works. But not with the Thread.currentThread().getContextClassLoader(). There I get:

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

现在,只要设置线程上下文类加载器,它就可以正常工作:

Now when just set the thread context class loader it works just fine:

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

但是,这有种古怪的感觉.这样的感觉以后会咬我.

But that has a hacky feeling to it. Feels like that will bite me later.

推荐答案

我不确定为什么您会感到惊讶.默认情况下,线程的上下文类加载器设置为其父级的类加载器,该类的开头则设置为系统类加载器.因此,假设您没有做任何特别的事情,则上下文类加载器就是系统类加载器,它与捆绑软件的类加载器不同,因此找不到资源.

I'm not sure why your surprised this happens. A thread's context classloader is, by default, set to the classloader of it's parent, which in the beginning is set to the system classloader. So, assuming you don't do anything special, the context classloader is the system classloader, which is not the same as your bundle's classloader, hence it can't find your resource.

我同意设置上下文类加载器对此有种古怪的感觉,但是某些库需要这样做.我会做类似的事情,

I agree that setting the context classloader has a hacky feel to it, but some libraries require this. I would do something like,

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

这篇关于使用上下文加载器加载资源失败,并显示NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆