使用上下文加载程序加载资源失败,出现NullPointerException
问题描述:
我只是想知道为什么我无法使用Felix OSGi中的线程上下文加载资源?我不应该触摸上下文加载器,我做错了什么或者是一个错误?使用上下文加载程序加载资源失败,出现NullPointerException
我有一个超级简单的包用一个简单的激活:
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());
但是,这有一个哈克的感觉吧。这样的感觉会在稍后咬我。
答
我不知道为什么你会惊讶这发生。默认情况下,一个线程的上下文类加载器被设置为它的父类的类加载器,它在开始时被设置为系统类加载器。所以,假设你没有做任何特别的事情,上下文类加载器就是系统类加载器,它与你的bundle的类加载器不一样,因此它找不到你的资源。
我同意设置上下文classloader有一个hacky的感觉,但有些库需要这样。我会做类似的,
ClassLoader previous = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
badlyBehavedLibraryCall();
Thread.currentThread().setContextClassLoader(previous);
那么我很奇怪的例外。如果资源不可见,通常会返回空白。好的,我会保留我的班加载器设置。当然,最后再试一试。 – Gamlor 2012-03-29 12:37:49