2012-03-28 95 views
3

我只是想知道为什么我无法使用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()); 

但是,这有一个哈克的感觉吧。这样的感觉会在稍后咬我。

回答

4

我不知道为什么你会惊讶这发生。默认情况下,一个线程的上下文类加载器被设置为它的父类的类加载器,它在开始时被设置为系统类加载器。所以,假设你没有做任何特别的事情,上下文类加载器就是系统类加载器,它与你的bundle的类加载器不一样,因此它找不到你的资源。

我同意设置上下文classloader有一个hacky的感觉,但有些库需要这样。我会做类似的,

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

那么我很奇怪的例外。如果资源不可见,通常会返回空白。好的,我会保留我的班加载器设置。当然,最后再试一试。 – Gamlor 2012-03-29 12:37:49

相关问题