0

次の問題があります。
AHashMapはプロパティの設定に使用され、キーは aClassLoaderです。
プロパティを設定するコードは次のとおりです ( 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));  
                }  
            }  
  }  

これらの値の 1 つがどこかにキャッシュされており、このハッシュマップをリセットする必要がありますが、問題は、これを行う方法がわからないことです。私はクラスをロードすることを考えました( a を使用する
ように委譲します)が、コードが次のことを行うことがわかります: axisURLClassLoadergetThreadContextClassLoader();

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

したがって、使用するクラスをロードするために使用したもの(つまり)ではなく、現在のスレッドのクラスローダーを使用すると思いますaxis
これを回避する方法はありますか?

注:アプリケーションの一部として既にロードさaxisれています。したがって、別のクラスローダーを介してリロードするという考えになります

4

1 に答える 1

1

問題のクラス ローダーがわかっている場合は、axis を呼び出す前にコンテキスト クラス ローダーを設定できます。

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

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

多くの場合、サーブレット コンテナーの外にいる場合にこれを行う必要がありますが、ライブラリはサーブレット コンテナー内にいると想定しています。たとえば、コンテキスト クラス ローダーのセマンティクスが定義されていない 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 に答える