0

我有以下问题。
AHashMap用于设置属性,键是 a 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));  
                }  
            }  
  }  

其中一个值缓存在某处,我需要重置此哈希图,但问题是我不知道如何执行此操作。
我想加载类(委托axis使用 a URLClassLoader),但我看到代码是getThreadContextClassLoader();这样的:

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

所以我认为它将使用我当前线程的类加载器,而不是我用来加载要使用的类的类加载器(即axis)。
那么有没有办法解决这个问题?

注意:我已经加载axis了我的应用程序的一部分。所以想法是通过不同的类加载器重新加载它

4

1 回答 1

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;
}

然后在与 Axis 交互时执行此操作:

ClassLoader context = ...;
new CCLTemplate<Void>() {
  public Void inContext() {
    // your code here.
    return null;
  }
}.execute(context);
于 2012-11-18T18:11:31.753 回答