2012-11-16 44 views
0

我有以下問題。
A HashMap用於設置屬性,關鍵是ClassLoader
,設置屬性的代碼如下(AxisProperties):在這種情況下將使用哪個類加載器?

public static void setProperty(String propertyName, String value, boolean isDefault){ 
     if(propertyName != null) 
      synchronized(propertiesCache) 
      { 
       ClassLoader classLoader = getThreadContextClassLoader(); 
       HashMap properties = (HashMap)propertiesCache.get(classLoader); 
       if(value == null) 
       { 
        if(properties != null) 
         properties.remove(propertyName); 
       } else 
       { 
        if(properties == null) 
        { 
         properties = new HashMap(); 
         propertiesCache.put(classLoader, properties); 
        } 
        properties.put(propertyName, new Value(value, isDefault)); 
       } 
      } 
    } 

其中一個值是緩存的地方,我需要重置此HashMap,但問題是我不知道如何做到這一點。
我想加載類(委託給axis使用URLClassLoader),但我看到的代碼確實getThreadContextClassLoader();是:

public ClassLoader getThreadContextClassLoader() 
{ 
    ClassLoader classLoader; 
     try 
     { 
      classLoader = Thread.currentThread().getContextClassLoader(); 
     } 
     catch(SecurityException e) 
     { 
      classLoader = null; 
     } 
     return classLoader; 
} 

因此,我認爲它會用我的當前線程不是一個的類加載器是我曾經加載要使用的類(即axis)。
那麼有沒有辦法解決這個問題?

注:我已經裝載axis作爲我的應用程序的一部分。這樣的想法是通過不同的類加載器加載它

+0

你是什麼propertiesCache的大小?我真的期望它是1,是嗎? –

+0

@GermannArlington:我真的不知道。我只設置了1個屬性,所以除非'Axis'將其他內容放在哈希表中,否則我只能假設** 1條目。我設置的和OP是關於 – Jim

+0

如果只有一個條目在這裏有一個HashMap的意義何在? P.S.你總是可以迭代地圖中的所有條目來找到你所擁有的。 –

回答

1

如果你知道有問題的類加載器,就可以進行調用到軸之前設置上下文類加載器:

ClassLoader key = ...; 
ClassLoader oldCtx = Thread.currentThread().getContextClassLoader(); 
try { 
    Thread.currentThread().setContextClassLoader(key); 

    // your code here. 
} 
finally { 
    Thread.currentThread().setContextClassLoader(oldCtx); 
} 

你經常要在你處於servlet容器之外的情況下執行此操作,但圖書館假定你在一個容器中。例如,您必須在OSGi容器中使用CXF執行此操作,其中未定義上下文類加載器的語義。您可以使用模板像這樣保持乾淨的東西:

public abstract class CCLTemplate<R> 
{ 
    public R execute(ClassLoader context) 
    throws Exception 
{ 
    ClassLoader oldCtx = Thread.currentThread().getContextClassLoader(); 
    try { 
     Thread.currentThread().setContextClassLoader(context); 

     return inContext(); 
    } 
    finally { 
     Thread.currentThread().setContextClassLoader(oldCtx); 
    } 
    } 

    public abstract R inContext() throws Exception; 
} 

然後做到這一點與軸交互時:

ClassLoader context = ...; 
new CCLTemplate<Void>() { 
    public Void inContext() { 
    // your code here. 
    return null; 
    } 
}.execute(context); 
相關問題