You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by sl...@apache.org on 2012/03/04 18:48:56 UTC

svn commit: r1296845 - in /tuscany/sca-java-2.x/trunk/modules: assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/ databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/ deployment/src/main/java/org/apache/tuscany/sca/depl...

Author: slaws
Date: Sun Mar  4 17:48:55 2012
New Revision: 1296845

URL: http://svn.apache.org/viewvc?rev=1296845&view=rev
Log:
TUSCANY-3312 - Copy JavaInterfaceFactory memory leak changes from 1.x + other related changes and some extensions to allow the cache to be reduced when contributions are unloaded in the domain node.

Modified:
    tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java
    tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java
    tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java
    tuscany/sca-java-2.x/trunk/modules/deployment/src/main/java/org/apache/tuscany/sca/deployment/impl/DeployerImpl.java
    tuscany/sca-java-2.x/trunk/modules/domain-node/pom.xml
    tuscany/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/impl/NodeImpl.java
    tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaElementImpl.java
    tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java
    tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java

Modified: tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java?rev=1296845&r1=1296844&r2=1296845&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/interfacedef/impl/DataTypeImpl.java Sun Mar  4 17:48:55 2012
@@ -18,6 +18,7 @@
  */
 package org.apache.tuscany.sca.interfacedef.impl;
 
+import java.lang.ref.WeakReference;
 import java.lang.reflect.Type;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -44,8 +45,8 @@ import org.apache.tuscany.sca.interfaced
  */
 public class DataTypeImpl<L> implements DataType<L> {
     private String dataBinding;
-    private Class<?> physical;
-    private Type genericType;
+    private WeakReference<Class<?>> physical;
+    private WeakReference<Type> genericType;
     private L logical;
     private Map<Class<?>, Object> metaDataMap;
 
@@ -78,8 +79,8 @@ public class DataTypeImpl<L> implements 
     public DataTypeImpl(String dataBinding, Class<?> physical, Type genericType, L logical) {
         super();
         this.dataBinding = dataBinding;
-        this.physical = physical;
-        this.genericType = genericType;
+        this.physical = new WeakReference<Class<?>>(physical);
+        this.genericType = new WeakReference<Type>(genericType);
         this.logical = logical;
     }
 
@@ -89,14 +90,14 @@ public class DataTypeImpl<L> implements 
      * @return the physical type used by the runtime
      */
     public Class<?> getPhysical() {
-        return physical;
+        return physical.get();
     }
 
     /**
      * @param physical the physical to set
      */
     public void setPhysical(Class<?> physical) {
-        this.physical = physical;
+        this.physical = new WeakReference<Class<?>>(physical);
     }
 
     /**
@@ -104,7 +105,7 @@ public class DataTypeImpl<L> implements 
      * @return The java generic type
      */
     public Type getGenericType() {
-        return genericType;
+        return genericType.get();
     }
 
     /**
@@ -112,7 +113,7 @@ public class DataTypeImpl<L> implements 
      * @param genericType
      */
     public void setGenericType(Type genericType) {
-        this.genericType = genericType;
+        this.genericType = new WeakReference<Type>(genericType);
     }
 
     /**
@@ -156,8 +157,8 @@ public class DataTypeImpl<L> implements 
     	StringBuilder b = new StringBuilder( 256 );
     	b.append( "DataType[" );
     	b.append( "dataBinding=" + ((dataBinding==null) ? "null" : dataBinding) );
-    	b.append( ", genericType=" + ((genericType==null) ? "null" : genericType) ); 
-    	b.append( ", physical=" + ((physical==null) ? "null" : physical) ); 
+    	b.append( ", genericType=" + ((genericType==null || genericType.get() == null) ? "null" : genericType) ); 
+    	b.append( ", physical=" + ((physical==null || physical.get() == null) ? "null" : physical) ); 
     	b.append( ", logical=" + ((logical==null) ? "null" : logical) );
     	b.append( ", metaData size=" + ((metaDataMap==null) ? "0" : metaDataMap.size()) );
     	b.append( "]" );
@@ -190,9 +191,9 @@ public class DataTypeImpl<L> implements 
         final int prime = 31;
         int result = 1;
         result = prime * result + ((dataBinding == null) ? 0 : dataBinding.hashCode());
-        result = prime * result + ((genericType == null) ? 0 : genericType.hashCode());
+        result = prime * result + ((genericType == null || genericType.get() == null) ? 0 : genericType.hashCode());
         result = prime * result + ((logical == null) ? 0 : logical.hashCode());
-        result = prime * result + ((physical == null) ? 0 : physical.hashCode());
+        result = prime * result + ((physical == null || physical.get() == null) ? 0 : physical.hashCode());
         return result;
     }
 
@@ -210,20 +211,20 @@ public class DataTypeImpl<L> implements 
                 return false;
         } else if (!dataBinding.equals(other.dataBinding))
             return false;
-        if (genericType == null) {
-            if (other.genericType != null)
+        if (genericType == null || genericType.get() == null) {
+            if (other.genericType != null && other.genericType.get() != null)
                 return false;
-        } else if (!genericType.equals(other.genericType))
+        } else if (!genericType.get().equals(other.genericType.get()))
             return false;
         if (logical == null) {
             if (other.logical != null)
                 return false;
         } else if (!logical.equals(other.logical))
             return false;
-        if (physical == null) {
-            if (other.physical != null)
+        if (physical == null || physical.get() == null) {
+            if (other.physical != null && other.physical.get() != null)
                 return false;
-        } else if (!physical.equals(other.physical))
+        } else if (!physical.get().equals(other.physical.get()))
             return false;
         return true;
     }

Modified: tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java?rev=1296845&r1=1296844&r2=1296845&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java Sun Mar  4 17:48:55 2012
@@ -59,6 +59,7 @@ import javax.xml.transform.Source;
 import org.apache.tuscany.sca.common.java.collection.LRUCache;
 import org.apache.tuscany.sca.core.ExtensionPointRegistry;
 import org.apache.tuscany.sca.extensibility.ClassLoaderContext;
+import org.oasisopen.sca.ServiceRuntimeException;
 
 /**
  * @version $Rev$ $Date$
@@ -403,6 +404,12 @@ public class JAXBContextCache {
                 }
             }
         }
+        public void removeCtx(K key){
+            Map<K,List<V>> map = softMap.get();
+            if (map !=null && key !=null){
+                map.remove(key);
+            }
+        }
     }
 
     /**
@@ -566,5 +573,61 @@ public class JAXBContextCache {
         }
     }
 
-}
+    public void removeJAXBContextFromPools(JAXBContext ctx){
+        if (mpool != null && ctx != null){
+            mpool.removeCtx(ctx);
+        }
+        if (upool != null && ctx !=null){
+            upool.removeCtx(ctx);
+        }
+    }
+    
+    /**
+     * Removes all the cached information relating to a contribution. The 
+     * contribution is identified by the contribution classloader passed in 
+     * as a parameter. This is used when a contribution is removed from 
+     * the runtime. 
+     * 
+     * @param contributionClassloader
+     */
+    public void removeJAXBContextForContribution(ClassLoader contributionClassloader){
+        if (cache != null){
+            try {
+                synchronized(cache) {
+                    Set<Object> objSet = cache.keySet();
+                    List<Object> toRemove = new ArrayList<Object>();
+                    Iterator<Object> i = objSet.iterator();
+                    while(i.hasNext()) {
+                        Object obj = i.next();
+                        if (obj instanceof Set){
+                            Set<Class> innerSet = (Set<Class>)obj;
+                            Iterator<Class> j = innerSet.iterator();
+                            loop:
+                            while(j.hasNext()) {
+                                Class cls = j.next();
+                                ClassLoader cl = cls.getClassLoader();
+                                while (cl != null){
+                                    if (cl == contributionClassloader){
+                                        toRemove.add(obj);
+                                        break loop;
+                                    }
+                                    // take account of generated classes
+                                    cl = cl.getParent();
+                                }
+                            }
+                        } 
+                    }
+                    for (Object obj : toRemove){
+                        JAXBContext ctx = cache.get(obj);
+                        removeJAXBContextFromPools(ctx);
+                        cache.remove(obj);
+                    }
+                }
+            } catch(Exception e) {
+                throw new ServiceRuntimeException(e);
+            }
+        }
+    }
 
+
+}

Modified: tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java?rev=1296845&r1=1296844&r2=1296845&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextHelper.java Sun Mar  4 17:48:55 2012
@@ -66,7 +66,7 @@ import org.apache.tuscany.sca.interfaced
  *
  * @version $Rev$ $Date$
  */
-// FIXME: [rfeng] We probably should turn this into a pluggable system service
+
 public final class JAXBContextHelper {
     private final JAXBContextCache cache;
     private final static SimpleTypeMapper SIMPLE_TYPE_MAPPER = new SimpleTypeMapperImpl();
@@ -587,4 +587,14 @@ public final class JAXBContextHelper {
         return name.substring(0, decap).toLowerCase() + name.substring(decap);
     }
 
+    public void removeJAXBContextForContribution(ClassLoader contributionClassloader){
+        cache.removeJAXBContextForContribution(contributionClassloader);
+    }
+    
+    /**
+     * Just for testing that the cache is being removed on stop
+     */
+    public JAXBContextCache getJAXBContextCache(){
+        return cache;
+    }
 }

Modified: tuscany/sca-java-2.x/trunk/modules/deployment/src/main/java/org/apache/tuscany/sca/deployment/impl/DeployerImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/deployment/src/main/java/org/apache/tuscany/sca/deployment/impl/DeployerImpl.java?rev=1296845&r1=1296844&r2=1296845&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/deployment/src/main/java/org/apache/tuscany/sca/deployment/impl/DeployerImpl.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/deployment/src/main/java/org/apache/tuscany/sca/deployment/impl/DeployerImpl.java Sun Mar  4 17:48:55 2012
@@ -226,7 +226,7 @@ public class DeployerImpl implements Dep
                     // Add the (empty) matchingExports List and report a warning
                     import_.setModelResolver(new DefaultImportModelResolver(matchingExports));
                     
-                    // push context here as the "stack" in this case is a list of nexted contributions
+                    // push context here as the "stack" in this case is a list of nested contributions
                     // through which imports have been chased which may not make much sense to the 
                     // user so just report the contribution in error
                     monitor.pushContext("Contribution: " + contribution.getURI());

Modified: tuscany/sca-java-2.x/trunk/modules/domain-node/pom.xml
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/domain-node/pom.xml?rev=1296845&r1=1296844&r2=1296845&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/domain-node/pom.xml (original)
+++ tuscany/sca-java-2.x/trunk/modules/domain-node/pom.xml Sun Mar  4 17:48:55 2012
@@ -37,12 +37,19 @@
             <artifactId>tuscany-node-impl</artifactId>
             <version>2.0-SNAPSHOT</version>
         </dependency>
+        
         <dependency>
             <groupId>org.apache.tuscany.sca</groupId>
             <artifactId>tuscany-assembly-xml</artifactId>
             <version>2.0-SNAPSHOT</version>
         </dependency>
         
+        <dependency>
+            <groupId>org.apache.tuscany.sca</groupId>
+            <artifactId>tuscany-databinding-jaxb</artifactId>
+            <version>2.0-SNAPSHOT</version>
+        </dependency>          
+        
          <dependency>
             <groupId>org.apache.tuscany.sca</groupId>
             <artifactId>tuscany-implementation-java-runtime</artifactId>
@@ -55,7 +62,7 @@
             <artifactId>tuscany-data-api</artifactId>
             <version>2.0-SNAPSHOT</version>
             <scope>test</scope>
-        </dependency>  
+        </dependency>          
                
         <dependency>
             <groupId>org.apache.tuscany.sca</groupId>

Modified: tuscany/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/impl/NodeImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/impl/NodeImpl.java?rev=1296845&r1=1296844&r2=1296845&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/impl/NodeImpl.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/impl/NodeImpl.java Sun Mar  4 17:48:55 2012
@@ -38,6 +38,7 @@ import javax.xml.stream.XMLStreamExcepti
 
 import org.apache.tuscany.sca.Node;
 import org.apache.tuscany.sca.TuscanyRuntime;
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
 import org.apache.tuscany.sca.assembly.Composite;
 import org.apache.tuscany.sca.assembly.xml.Utils;
 import org.apache.tuscany.sca.common.java.io.IOHelper;
@@ -51,8 +52,11 @@ import org.apache.tuscany.sca.contributi
 import org.apache.tuscany.sca.contribution.resolver.ExtensibleModelResolver;
 import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
 import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
 import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.databinding.jaxb.JAXBContextHelper;
 import org.apache.tuscany.sca.deployment.Deployer;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
 import org.apache.tuscany.sca.monitor.Monitor;
 import org.apache.tuscany.sca.monitor.ValidationException;
 import org.apache.tuscany.sca.runtime.ActivationException;
@@ -73,6 +77,8 @@ public class NodeImpl implements Node {
     private CompositeActivator compositeActivator;
     private DomainRegistry domainRegistry;
     private ExtensionPointRegistry extensionPointRegistry;
+    private UtilityExtensionPoint utilityExtensionPoint;
+    private FactoryExtensionPoint factoryExtensionPoint;
     private TuscanyRuntime tuscanyRuntime;
     
     private Map<String, Contribution> loadedContributions = new ConcurrentHashMap<String, Contribution>();
@@ -95,8 +101,11 @@ public class NodeImpl implements Node {
         this.domainRegistry = domainRegistry;
         this.extensionPointRegistry = extensionPointRegistry;
         this.tuscanyRuntime = tuscanyRuntime;
-
-        extensionPointRegistry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(ActiveNodes.class).getActiveNodes().add(this);
+        
+        utilityExtensionPoint = extensionPointRegistry.getExtensionPoint(UtilityExtensionPoint.class);
+        factoryExtensionPoint = extensionPointRegistry.getExtensionPoint(FactoryExtensionPoint.class);
+        
+        utilityExtensionPoint.getUtility(ActiveNodes.class).getActiveNodes().add(this);
 
         domainRegistry.addContributionListener(new ContributionListener() {
             public void contributionInstalled(String uri) {
@@ -226,6 +235,21 @@ public class NodeImpl implements Node {
     }
     
     public void uninstallContribution(String contributionURI) {
+        // give the runtime the chance to release only artifacts
+        // held by this contribution (and its classloader)
+        Contribution contribution = loadedContributions.get(contributionURI);
+        if (contribution != null) {
+            ClassLoader contributionClassloader = contribution.getClassLoader();  
+            
+            // These are very specific at the moment as there is no 
+            // common lifecycle interface at this level
+            JAXBContextHelper jaxbContextHelper = utilityExtensionPoint.getUtility(JAXBContextHelper.class);
+            jaxbContextHelper.removeJAXBContextForContribution(contributionClassloader);
+            
+            JavaInterfaceFactory javaInterfaceFactory = factoryExtensionPoint.getFactory(JavaInterfaceFactory.class);
+            javaInterfaceFactory.removeInterfacesForContribution(contributionClassloader);
+        }
+        
         domainRegistry.uninstallContribution(contributionURI);
         
         // remove any stopped composite that used the contribution
@@ -236,6 +260,7 @@ public class NodeImpl implements Node {
                 i.remove();
             }
         }
+        
         if (logger.isLoggable(quietLogging? Level.FINE : Level.INFO)) logger.log(quietLogging? Level.FINE : Level.INFO, "uninstallContribution: " + contributionURI);
     }
     

Modified: tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaElementImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaElementImpl.java?rev=1296845&r1=1296844&r2=1296845&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaElementImpl.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/JavaElementImpl.java Sun Mar  4 17:48:55 2012
@@ -21,6 +21,7 @@ package org.apache.tuscany.sca.implement
 
 import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
+import java.lang.ref.WeakReference;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
@@ -36,8 +37,8 @@ import java.lang.reflect.Type;
 public class JavaElementImpl {
     private AnnotatedElement anchor;
     private ElementType elementType;
-    private Class<?> type;
-    private Type genericType;
+    private WeakReference<Class<?>> type;
+    private WeakReference<Type> genericType;
     private int index = -1;
     private String name;
     private Class<? extends Annotation> classifer;
@@ -45,24 +46,24 @@ public class JavaElementImpl {
     public JavaElementImpl(Class<?> cls) {
         this.anchor = cls;
         this.elementType = ElementType.TYPE;
-        this.type = cls;
-        this.genericType = cls;
+        this.type = new WeakReference<Class<?>>(cls);
+        this.genericType = new WeakReference<Type>(cls);
         this.name = cls.getName();
     }
 
     public JavaElementImpl(Field field) {
         this.anchor = field;
         this.elementType = ElementType.FIELD;
-        this.type = field.getType();
-        this.genericType = field.getGenericType();
+        this.type = new WeakReference<Class<?>>(field.getType());
+        this.genericType = new WeakReference<Type>(field.getGenericType());
         this.name = field.getName();
     }
 
     public JavaElementImpl(Constructor<?> constructor, int index) {
         this.anchor = constructor;
         this.elementType = ElementType.PARAMETER;
-        this.type = constructor.getParameterTypes()[index];
-        this.genericType = constructor.getGenericParameterTypes()[index];
+        this.type = new WeakReference<Class<?>>(constructor.getParameterTypes()[index]);
+        this.genericType = new WeakReference<Type>(constructor.getGenericParameterTypes()[index]);
         this.index = index;
         this.name = "";
     }
@@ -70,8 +71,8 @@ public class JavaElementImpl {
     public JavaElementImpl(Method method, int index) {
         this.anchor = method;
         this.elementType = ElementType.PARAMETER;
-        this.type = method.getParameterTypes()[index];
-        this.genericType = method.getGenericParameterTypes()[index];
+        this.type = new WeakReference<Class<?>>(method.getParameterTypes()[index]);
+        this.genericType = new WeakReference<Type>(method.getGenericParameterTypes()[index]);
         this.index = index;
         this.name = "";
     }
@@ -86,7 +87,7 @@ public class JavaElementImpl {
      */
     public JavaElementImpl(String name, Class<?> type, Class<? extends Annotation> classifer) {
         super();
-        this.type = type;
+        this.type = new WeakReference<Class<?>>(type);
         this.name = name;
         this.classifer = classifer;
     }
@@ -109,7 +110,7 @@ public class JavaElementImpl {
      * @return the genericType
      */
     public Type getGenericType() {
-        return genericType;
+        return genericType.get();
     }
 
     /**
@@ -123,7 +124,7 @@ public class JavaElementImpl {
      * @return the type
      */
     public Class<?> getType() {
-        return type;
+        return type.get();
     }
 
     /**

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java?rev=1296845&r1=1296844&r2=1296845&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java Sun Mar  4 17:48:55 2012
@@ -96,4 +96,13 @@ public interface JavaInterfaceFactory {
      * @return
      */
     List<JavaInterfaceVisitor> getInterfaceVisitors();
+    
+    /**
+     * Remove the interfaces that have been registered for 
+     * the contribution identified by the contribution class
+     * loader provided
+     * 
+     * @param contributionClassloader
+     */
+    void removeInterfacesForContribution(ClassLoader contributionClassloader);
 }

Modified: tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
URL: http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java?rev=1296845&r1=1296844&r2=1296845&view=diff
==============================================================================
--- tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java (original)
+++ tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java Sun Mar  4 17:48:55 2012
@@ -21,8 +21,10 @@ package org.apache.tuscany.sca.interface
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.WeakHashMap;
 
 import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
@@ -31,6 +33,7 @@ import org.apache.tuscany.sca.interfaced
 import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
 import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
 import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor;
+import org.oasisopen.sca.ServiceRuntimeException;
 
 /**
  * A factory for the Java model.
@@ -112,4 +115,48 @@ public abstract class JavaInterfaceFacto
         op.setName(method.getName());
         return op;
     }
+    
+    /**
+     * Removes all the cached information relating to a contribution. The 
+     * contribution is identified by the contribution classloader passed in 
+     * as a parameter. This is used when a contribution is removed from 
+     * the runtime. 
+     * 
+     * @param contributionClassloader
+     */
+    public void removeInterfacesForContribution(ClassLoader contributionClassloader){
+        removeInterfacesFromCache(contributionClassloader, normalCache);
+        removeInterfacesFromCache(contributionClassloader, forceRemotableCache);
+    }
+    
+    private void removeInterfacesFromCache(ClassLoader contributionClassloader, Map<Class<?>, JavaInterface> cache){
+        try {
+            synchronized(cache) {
+                Set<Class<?>> clsSet = cache.keySet();
+                Iterator<Class<?>> i = clsSet.iterator();
+                while (i.hasNext()) {
+                    Class<?> cls = i.next();
+                    if (cls.getClassLoader() == contributionClassloader) {
+                        i.remove();
+                    }
+                }
+            }
+        } catch(Exception e) {
+            throw new ServiceRuntimeException(e);
+        }
+    }
+    
+    /**
+     * For testing so we can check that the cache is being cleared
+     */
+    public Map<Class<?>, JavaInterface> getNormalCache(){
+        return normalCache;
+    }
+    
+    /**
+     * For testing so we can check that the cache is being cleared
+     */
+    public Map<Class<?>, JavaInterface> getForceRemotableCache(){
+        return forceRemotableCache;
+    }
 }