You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2006/08/01 19:56:05 UTC

svn commit: r427662 - in /webservices/axis2/trunk/java/modules/core/src/org/apache/axis2: ./ context/ receivers/ transport/http/server/ util/

Author: dims
Date: Tue Aug  1 10:56:04 2006
New Revision: 427662

URL: http://svn.apache.org/viewvc?rev=427662&view=rev
Log:
- Add destroy method to Service interface.
- Fix spelling mistakes in ConfigurationContext and SessionManager
- Fix for AXIS2-400 - Classloader doesn't work with Spring inside an AAR
- Possible Fix for AXIS2-537 - Service classloader problem

Notes:
- Basically added a MultiParentClassLoader from Geronimo codebase which
  can lookup either the Service's classloader or the current TCCL
- Call the set for the MPCL before invokeBusinessLogic and reset it back
  after invokeBusinessLogic is over in a finally block



Added:
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/util/MultiParentClassLoader.java
Modified:
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/Service.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/context/ConfigurationContext.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInMessageReceiver.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInOutAsyncMessageReceiver.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInOutSyncMessageReceiver.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractMessageReceiver.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractRobustInMessageReceiver.java
    webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/http/server/SessionManager.java

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/Service.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/Service.java?rev=427662&r1=427661&r2=427662&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/Service.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/Service.java Tue Aug  1 10:56:04 2006
@@ -40,4 +40,10 @@
      * @param operationContext
      */
     public void setOperationContext(OperationContext operationContext);
+
+    /**
+     * This method is called when the service is destroyed.
+     * @param sc
+     */
+    public void destroy(ServiceContext sc);
 }

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/context/ConfigurationContext.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/context/ConfigurationContext.java?rev=427662&r1=427661&r2=427662&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/context/ConfigurationContext.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/context/ConfigurationContext.java Tue Aug  1 10:56:04 2006
@@ -333,7 +333,7 @@
                 if ((currentTime - serviceGroupContext.getLastTouchedTime()) >
                         getServiceGroupContextTimoutInterval()) {
                     sgCtxtMapKeyIter.remove();
-                    cleanupServiceContextes(serviceGroupContext);
+                    cleanupServiceContexts(serviceGroupContext);
                 }
             }
         }
@@ -347,7 +347,7 @@
         this.listenerManager = listenerManager;
     }
 
-    private void cleanupServiceContextes(ServiceGroupContext serviceGroupContext) {
+    private void cleanupServiceContexts(ServiceGroupContext serviceGroupContext) {
         Iterator serviceContecxtes = serviceGroupContext.getServiceContexts();
         while (serviceContecxtes.hasNext()) {
             ServiceContext serviceContext = (ServiceContext) serviceContecxtes.next();
@@ -365,14 +365,14 @@
             while (applicationScopeSgs.hasNext()) {
                 ServiceGroupContext serviceGroupContext =
                         (ServiceGroupContext) applicationScopeSgs.next();
-                cleanupServiceContextes(serviceGroupContext);
+                cleanupServiceContexts(serviceGroupContext);
             }
         }
         if (serviceGroupContextMap.size() > 0) {
             Iterator sopaSessionSgs = serviceGroupContextMap.values().iterator();
             while (sopaSessionSgs.hasNext()) {
                 ServiceGroupContext serviceGroupContext = (ServiceGroupContext) sopaSessionSgs.next();
-                cleanupServiceContextes(serviceGroupContext);
+                cleanupServiceContexts(serviceGroupContext);
             }
         }
     }

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInMessageReceiver.java?rev=427662&r1=427661&r2=427662&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInMessageReceiver.java Tue Aug  1 10:56:04 2006
@@ -31,6 +31,11 @@
     public abstract void invokeBusinessLogic(MessageContext inMessage) throws AxisFault;
 
     public final void receive(final MessageContext messageCtx) throws AxisFault {
-        invokeBusinessLogic(messageCtx);
+        try {
+            saveTCCL(messageCtx);
+            invokeBusinessLogic(messageCtx);
+        } finally {
+            restoreTCCL();
+        }
     }
 }

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInOutAsyncMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInOutAsyncMessageReceiver.java?rev=427662&r1=427661&r2=427662&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInOutAsyncMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInOutAsyncMessageReceiver.java Tue Aug  1 10:56:04 2006
@@ -56,7 +56,12 @@
                 try {
                     MessageContext newmsgCtx = Utils.createOutMessageContext(messageCtx);
                     newmsgCtx.getOperationContext().addMessageContext(newmsgCtx);
-                    invokeBusinessLogic(messageCtx, newmsgCtx);
+                    try {
+                        saveTCCL(messageCtx);
+                        invokeBusinessLogic(messageCtx, newmsgCtx);
+                    } finally {
+                        restoreTCCL();
+                    }
                     callback.handleResult(newmsgCtx);
                 } catch (AxisFault e) {
                     try {

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInOutSyncMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInOutSyncMessageReceiver.java?rev=427662&r1=427661&r2=427662&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInOutSyncMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractInOutSyncMessageReceiver.java Tue Aug  1 10:56:04 2006
@@ -34,7 +34,12 @@
         MessageContext outMsgContext = Utils.createOutMessageContext(msgContext);
         outMsgContext.getOperationContext().addMessageContext(outMsgContext);
 
-        invokeBusinessLogic(msgContext, outMsgContext);
+        try {
+            saveTCCL(msgContext);
+            invokeBusinessLogic(msgContext, outMsgContext);
+        } finally {
+            restoreTCCL();
+        }
 
         AxisEngine engine =
                 new AxisEngine(

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractMessageReceiver.java?rev=427662&r1=427661&r2=427662&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractMessageReceiver.java Tue Aug  1 10:56:04 2006
@@ -22,6 +22,7 @@
 import org.apache.axiom.soap.SOAP12Constants;
 import org.apache.axiom.soap.SOAPFactory;
 import org.apache.axis2.AxisFault;
+import org.apache.axis2.util.MultiParentClassLoader;
 import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.context.ServiceContext;
 import org.apache.axis2.description.AxisService;
@@ -31,11 +32,29 @@
 import org.apache.axis2.i18n.Messages;
 
 import java.lang.reflect.Method;
+import java.net.URL;
 
 public abstract class AbstractMessageReceiver implements MessageReceiver {
     public static final String SERVICE_CLASS = "ServiceClass";
     public static final String SERVICE_OBJECT_SUPPLIER = "ServiceObjectSupplier";
     public static final String SCOPE = "scope";
+
+    protected void saveTCCL(MessageContext msgContext) {
+        if (msgContext.getAxisService() != null &&
+                msgContext.getAxisService().getClassLoader() != null) {
+            Thread.currentThread().setContextClassLoader(new MultiParentClassLoader(new URL[]{}, new ClassLoader[]{
+                    msgContext.getAxisService().getClassLoader(),
+                    Thread.currentThread().getContextClassLoader(),
+            }));
+        }
+    }
+
+    protected void restoreTCCL() {
+        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+        if (tccl != null && tccl instanceof MultiParentClassLoader) {
+            Thread.currentThread().setContextClassLoader(((MultiParentClassLoader) tccl).getParents()[1]);
+        }
+    }
 
     /**
      * Method makeNewServiceObject.

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractRobustInMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractRobustInMessageReceiver.java?rev=427662&r1=427661&r2=427662&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractRobustInMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/receivers/AbstractRobustInMessageReceiver.java Tue Aug  1 10:56:04 2006
@@ -31,6 +31,11 @@
     public abstract void invokeBusinessLogic(MessageContext inMessage) throws AxisFault;
 
     public final void receive(final MessageContext messageCtx) throws AxisFault {
-        invokeBusinessLogic(messageCtx);
+        try {
+            saveTCCL(messageCtx);
+            invokeBusinessLogic(messageCtx);
+        } finally {
+            restoreTCCL();
+        }
     }
 }

Modified: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/http/server/SessionManager.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/http/server/SessionManager.java?rev=427662&r1=427661&r2=427662&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/http/server/SessionManager.java (original)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/http/server/SessionManager.java Tue Aug  1 10:56:04 2006
@@ -81,14 +81,14 @@
                 if (serviceGroupContext != null) {
                     while (serviceGroupContext.hasNext()) {
                         ServiceGroupContext groupContext = (ServiceGroupContext) serviceGroupContext.next();
-                        cleanupServiceContextes(groupContext);
+                        cleanupServiceContexts(groupContext);
                     }
                 }
             }
         }
     }
 
-    private void cleanupServiceContextes(final ServiceGroupContext serviceGroupContext) {
+    private void cleanupServiceContexts(final ServiceGroupContext serviceGroupContext) {
         for (Iterator it = serviceGroupContext.getServiceContexts(); it.hasNext(); ) {
             ServiceContext serviceContext = (ServiceContext) it.next();
             try {

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/util/MultiParentClassLoader.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/util/MultiParentClassLoader.java?rev=427662&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/util/MultiParentClassLoader.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/util/MultiParentClassLoader.java Tue Aug  1 10:56:04 2006
@@ -0,0 +1,403 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.axis2.util;
+
+import java.beans.Introspector;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * A MultiParentClassLoader is a simple extension of the URLClassLoader that simply changes the single parent class
+ * loader model to support a list of parent class loaders.  Each operation that accesses a parent, has been replaced
+ * with a operation that checks each parent in order.  This getParent method of this class will always return null,
+ * which may be interpreted by the calling code to mean that this class loader is a direct child of the system class
+ * loader.
+ *
+ * @version $Rev$ $Date$
+ */
+public class MultiParentClassLoader extends URLClassLoader {
+    private final ClassLoader[] parents;
+    private final boolean inverseClassLoading;
+    private final String[] hiddenClasses;
+    private final String[] nonOverridableClasses;
+    private final String[] hiddenResources;
+    private final String[] nonOverridableResources;
+    private boolean destroyed = false;
+
+    /**
+     * Creates a named class loader with no parents.
+     *
+     * @param urls the urls from which this class loader will classes and resources
+     */
+    public MultiParentClassLoader(URL[] urls) {
+        super(urls);
+        parents = new ClassLoader[]{ClassLoader.getSystemClassLoader()};
+        inverseClassLoading = false;
+        hiddenClasses = new String[0];
+        nonOverridableClasses = new String[0];
+        hiddenResources = new String[0];
+        nonOverridableResources = new String[0];
+    }
+
+
+    /**
+     * Creates a named class loader as a child of the specified parent.
+     *
+     * @param urls   the urls from which this class loader will classes and resources
+     * @param parent the parent of this class loader
+     */
+    public MultiParentClassLoader(URL[] urls, ClassLoader parent) {
+        this(urls, new ClassLoader[]{parent});
+    }
+
+    public MultiParentClassLoader(URL[] urls, ClassLoader parent, boolean inverseClassLoading, String[] hiddenClasses, String[] nonOverridableClasses) {
+        this(urls, new ClassLoader[]{parent}, inverseClassLoading, hiddenClasses, nonOverridableClasses);
+    }
+
+    /**
+     * Creates a named class loader as a child of the specified parent and using the specified URLStreamHandlerFactory
+     * for accessing the urls..
+     *
+     * @param urls    the urls from which this class loader will classes and resources
+     * @param parent  the parent of this class loader
+     * @param factory the URLStreamHandlerFactory used to access the urls
+     */
+    public MultiParentClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) {
+        this(urls, new ClassLoader[]{parent}, factory);
+    }
+
+    /**
+     * Creates a named class loader as a child of the specified parents.
+     *
+     * @param urls    the urls from which this class loader will classes and resources
+     * @param parents the parents of this class loader
+     */
+    public MultiParentClassLoader(URL[] urls, ClassLoader[] parents) {
+        super(urls);
+        this.parents = copyParents(parents);
+        inverseClassLoading = false;
+        hiddenClasses = new String[0];
+        nonOverridableClasses = new String[0];
+        hiddenResources = new String[0];
+        nonOverridableResources = new String[0];
+    }
+
+    public MultiParentClassLoader(URL[] urls, ClassLoader[] parents, boolean inverseClassLoading, Collection hiddenClasses, Collection nonOverridableClasses) {
+        this(urls, parents, inverseClassLoading, (String[]) hiddenClasses.toArray(new String[hiddenClasses.size()]), (String[]) nonOverridableClasses.toArray(new String[nonOverridableClasses.size()]));
+    }
+
+    public MultiParentClassLoader(URL[] urls, ClassLoader[] parents, boolean inverseClassLoading, String[] hiddenClasses, String[] nonOverridableClasses) {
+        super(urls);
+        this.parents = copyParents(parents);
+        this.inverseClassLoading = inverseClassLoading;
+        this.hiddenClasses = hiddenClasses;
+        this.nonOverridableClasses = nonOverridableClasses;
+        hiddenResources = toResources(hiddenClasses);
+        nonOverridableResources = toResources(nonOverridableClasses);
+    }
+
+    private String[] toResources(String[] classes) {
+        String[] resources = new String[classes.length];
+        for (int i = 0; i < classes.length; i++) {
+            String className = classes[i];
+            resources[i] = className.replace('.', '/');
+        }
+        return resources;
+    }
+
+    /**
+     * Creates a named class loader as a child of the specified parents and using the specified URLStreamHandlerFactory
+     * for accessing the urls..
+     *
+     * @param urls    the urls from which this class loader will classes and resources
+     * @param parents the parents of this class loader
+     * @param factory the URLStreamHandlerFactory used to access the urls
+     */
+    public MultiParentClassLoader(URL[] urls, ClassLoader[] parents, URLStreamHandlerFactory factory) {
+        super(urls, null, factory);
+        this.parents = copyParents(parents);
+        inverseClassLoading = false;
+        hiddenClasses = new String[0];
+        nonOverridableClasses = new String[0];
+        hiddenResources = new String[0];
+        nonOverridableResources = new String[0];
+    }
+
+    private static ClassLoader[] copyParents(ClassLoader[] parents) {
+        ClassLoader[] newParentsArray = new ClassLoader[parents.length];
+        for (int i = 0; i < parents.length; i++) {
+            ClassLoader parent = parents[i];
+            if (parent == null) {
+                throw new NullPointerException("parent[" + i + "] is null");
+            }
+            newParentsArray[i] = parent;
+        }
+        return newParentsArray;
+    }
+
+    /**
+     * Gets the parents of this class loader.
+     *
+     * @return the parents of this class loader
+     */
+    public ClassLoader[] getParents() {
+        return parents;
+    }
+
+    public void addURL(URL url) {
+        // todo this needs a security check
+        super.addURL(url);
+    }
+
+    protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        //
+        // Check if class is in the loaded classes cache
+        //
+        Class cachedClass = findLoadedClass(name);
+        if (cachedClass != null) {
+            return resolveClass(cachedClass, resolve);
+        }
+
+        //
+        // if we are using inverse class loading, check local urls first
+        //
+        if (inverseClassLoading && !isDestroyed() && !isNonOverridableClass(name)) {
+            try {
+                Class clazz = findClass(name);
+                return resolveClass(clazz, resolve);
+            } catch (ClassNotFoundException ignored) {
+            }
+        }
+
+        //
+        // Check parent class loaders
+        //
+        if (!isHiddenClass(name)) {
+            for (int i = 0; i < parents.length; i++) {
+                ClassLoader parent = parents[i];
+                try {
+                    Class clazz = parent.loadClass(name);
+                    return resolveClass(clazz, resolve);
+                } catch (ClassNotFoundException ignored) {
+                    // this parent didn't have the class; try the next one
+                }
+            }
+        }
+
+        //
+        // if we are not using inverse class loading, check local urls now
+        //
+        // don't worry about excluding non-overridable classes here... we
+        // have alredy checked he parent and the parent didn't have the
+        // class, so we can override now
+        if (!isDestroyed()) {
+            try {
+                Class clazz = findClass(name);
+                return resolveClass(clazz, resolve);
+            } catch (ClassNotFoundException ignored) {
+            }
+        }
+
+        throw new ClassNotFoundException(name);
+    }
+
+    private boolean isNonOverridableClass(String name) {
+        for (int i = 0; i < nonOverridableClasses.length; i++) {
+            if (name.startsWith(nonOverridableClasses[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isHiddenClass(String name) {
+        for (int i = 0; i < hiddenClasses.length; i++) {
+            if (name.startsWith(hiddenClasses[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private Class resolveClass(Class clazz, boolean resolve) {
+        if (resolve) {
+            resolveClass(clazz);
+        }
+        return clazz;
+    }
+
+    public URL getResource(String name) {
+        if (isDestroyed()) {
+            return null;
+        }
+
+        //
+        // if we are using inverse class loading, check local urls first
+        //
+        if (inverseClassLoading && !isDestroyed() && !isNonOverridableResource(name)) {
+            URL url = findResource(name);
+            if (url != null) {
+                return url;
+            }
+        }
+
+        //
+        // Check parent class loaders
+        //
+        if (!isHiddenResource(name)) {
+            for (int i = 0; i < parents.length; i++) {
+                ClassLoader parent = parents[i];
+                URL url = parent.getResource(name);
+                if (url != null) {
+                    return url;
+                }
+            }
+        }
+
+        //
+        // if we are not using inverse class loading, check local urls now
+        //
+        // don't worry about excluding non-overridable resources here... we
+        // have alredy checked he parent and the parent didn't have the
+        // resource, so we can override now
+        if (!isDestroyed()) {
+            // parents didn't have the resource; attempt to load it from my urls
+            return findResource(name);
+        }
+
+        return null;
+    }
+
+    public Enumeration findResources(String name) throws IOException {
+        if (isDestroyed()) {
+            return Collections.enumeration(Collections.EMPTY_SET);
+        }
+
+        List resources = new ArrayList();
+
+        //
+        // if we are using inverse class loading, add the resources from local urls first
+        //
+        if (inverseClassLoading && !isDestroyed()) {
+            List myResources = Collections.list(super.findResources(name));
+            resources.addAll(myResources);
+        }
+
+        //
+        // Add parent resources
+        //
+        for (int i = 0; i < parents.length; i++) {
+            ClassLoader parent = parents[i];
+            List parentResources = Collections.list(parent.getResources(name));
+            resources.addAll(parentResources);
+        }
+
+        //
+        // if we are not using inverse class loading, add the resources from local urls now
+        //
+        if (!inverseClassLoading && !isDestroyed()) {
+            List myResources = Collections.list(super.findResources(name));
+            resources.addAll(myResources);
+        }
+
+        return Collections.enumeration(resources);
+    }
+
+    private boolean isNonOverridableResource(String name) {
+        for (int i = 0; i < nonOverridableResources.length; i++) {
+            if (name.startsWith(nonOverridableResources[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isHiddenResource(String name) {
+        for (int i = 0; i < hiddenResources.length; i++) {
+            if (name.startsWith(hiddenResources[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public String toString() {
+        return "[" + getClass().getName() + "]";
+    }
+
+    public synchronized boolean isDestroyed() {
+        return destroyed;
+    }
+
+    public void destroy() {
+        synchronized(this) {
+            if (destroyed) return;
+            destroyed = true;
+        }
+
+        LogFactory.release(this);
+//        clearSoftCache(ObjectInputStream.class, "subclassAudits");
+//        clearSoftCache(ObjectOutputStream.class, "subclassAudits");
+//        clearSoftCache(ObjectStreamClass.class, "localDescs");
+//        clearSoftCache(ObjectStreamClass.class, "reflectors");
+
+        // The beanInfoCache in java.beans.Introspector will hold on to Classes which
+        // it has introspected. If we don't flush the cache, we may run out of
+        // Permanent Generation space.
+        Introspector.flushCaches();
+    }
+
+//    private static final Object lock = new Object();
+//    private static boolean clearSoftCacheFailed = false;
+//
+//    private static void clearSoftCache(Class clazz, String fieldName) {
+//        Map cache = null;
+//        try {
+//            Field f = clazz.getDeclaredField(fieldName);
+//            f.setAccessible(true);
+//            cache = (Map) f.get(null);
+//        } catch (Throwable e) {
+//            synchronized (lock) {
+//                if (!clearSoftCacheFailed) {
+//                    clearSoftCacheFailed = true;
+//                    LogFactory.getLog(ConfigurationClassLoader.class).error("Unable to clear SoftCache field " + fieldName + " in class " + clazz);
+//                }
+//            }
+//        }
+//
+//        if (cache != null) {
+//            synchronized (cache) {
+//                cache.clear();
+//            }
+//        }
+//    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org