[英]Which classloader will be used in this case?
我有以下问题。
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));
}
}
}
这些值之一缓存在某处,我需要重置此哈希图,但是问题是我不知道该怎么做。
我想加载类(使用URLClassLoader
委托到axis
),但我看到代码确实getThreadContextClassLoader();
这是:
public ClassLoader getThreadContextClassLoader()
{
ClassLoader classLoader;
try
{
classLoader = Thread.currentThread().getContextClassLoader();
}
catch(SecurityException e)
{
classLoader = null;
}
return classLoader;
}
因此,我认为它将使用当前线程的类加载器,而不是用于加载要使用的类的类加载器(即axis
)。
那么有办法解决吗?
注意:我已经在应用程序中加载了axis
。 因此,想法是通过另一个类加载器重新加载它
如果知道相关的类加载器,则可以在调用轴之前设置上下文类加载器:
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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.