2012-03-28 42 views
3

なぜ、Felix OSGiのスレッドコンテキストローダーでリソースをロードできないのでしょうか?コンテキストローダーに触れてはいけないのですか?何か間違っているのですか、バグですか?コンテキストローダーでリソースをロードするとNullPointerExceptionが発生する

私は、単純なアクティベーターで超簡単なバンドルしました:今Activator.class.getClassLoader作品とクラスローダを持つとリソースをロードする

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!!"); 
    } 
} 

を。しかし、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

私はあなたの驚きがなぜ起こるのか分かりません。スレッドのコンテキストクラスローダーは、デフォルトでは、その親のクラスローダーに設定されています(最初はシステムクラスローダーに設定されています)。したがって、特別なことをしないと仮定すると、コンテキストクラスローダーはシステムクラスローダーであり、バンドルのクラスローダーと同じではないため、リソースを見つけることができません。

私は、コンテキストクラスローダーの設定にハッキリ感があることに同意しますが、ライブラリによってはこれが必要です。私は何かのようにするだろう

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

私は奇妙な例外に驚いた。通常、リソースが表示されていない場合はnullが戻されます。さて、私はクラスローダーの設定を維持します。もちろん、try-finallyでそれを元に戻します。 – Gamlor

関連する問題