TUSCANY-3312 remove circular references where a class is used as the key of a map and the value of the map also references the class. The weakness of the map never comes into play as there is always a reference to the key (held by the value). This all pins the app classloader and causes a leak on each app start/stop cycle
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@828086 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ce8ce56837
commit
685e099602
3 changed files with 34 additions and 32 deletions
|
@ -33,7 +33,7 @@ public class SCAProxy extends Proxy
|
|||
// This is a cache containing the proxy class constructor for each business interface.
|
||||
// This improves performance compared to calling Proxy.newProxyInstance()
|
||||
// every time that a proxy is needed.
|
||||
private static WeakHashMap cache = new WeakHashMap<Class, Object>();
|
||||
private static WeakHashMap cache = new WeakHashMap<String, Object>();
|
||||
|
||||
public static Object newProxyInstance(ClassLoader classloader, Class aclass[], InvocationHandler invocationhandler)
|
||||
throws IllegalArgumentException
|
||||
|
@ -44,13 +44,13 @@ public class SCAProxy extends Proxy
|
|||
// Lookup cached constructor. aclass[0] is the reference's business interface.
|
||||
Constructor proxyCTOR;
|
||||
synchronized(cache) {
|
||||
proxyCTOR = (Constructor) cache.get(aclass[0]);
|
||||
proxyCTOR = (Constructor) cache.get(aclass[0].hashCode());
|
||||
}
|
||||
if(proxyCTOR == null) {
|
||||
Class proxyClass = getProxyClass(classloader, aclass);
|
||||
proxyCTOR = proxyClass.getConstructor(constructorParams);
|
||||
synchronized(cache){
|
||||
cache.put(aclass[0],proxyCTOR);
|
||||
cache.put(aclass[0].hashCode(),proxyCTOR);
|
||||
}
|
||||
}
|
||||
return proxyCTOR.newInstance(new Object[] { invocationhandler });
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.apache.tuscany.sca.implementation.java.impl;
|
|||
|
||||
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;
|
||||
|
@ -51,24 +52,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 = "";
|
||||
}
|
||||
|
@ -76,8 +77,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 = "";
|
||||
}
|
||||
|
@ -92,7 +93,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;
|
||||
}
|
||||
|
@ -115,7 +116,7 @@ public class JavaElementImpl {
|
|||
* @return the genericType
|
||||
*/
|
||||
public Type getGenericType() {
|
||||
return genericType;
|
||||
return genericType.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,7 +130,7 @@ public class JavaElementImpl {
|
|||
* @return the type
|
||||
*/
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
return type.get();
|
||||
}
|
||||
|
||||
public Annotation[] getAnnotations() {
|
||||
|
|
|
@ -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;
|
||||
|
@ -43,8 +44,8 @@ import org.apache.tuscany.sca.interfacedef.DataType;
|
|||
*/
|
||||
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;
|
||||
|
||||
|
@ -77,8 +78,8 @@ public class DataTypeImpl<L> implements DataType<L> {
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -88,14 +89,14 @@ public class DataTypeImpl<L> implements DataType<L> {
|
|||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +104,7 @@ public class DataTypeImpl<L> implements DataType<L> {
|
|||
* @return The java generic type
|
||||
*/
|
||||
public Type getGenericType() {
|
||||
return genericType;
|
||||
return genericType.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,7 +112,7 @@ public class DataTypeImpl<L> implements DataType<L> {
|
|||
* @param genericType
|
||||
*/
|
||||
public void setGenericType(Type genericType) {
|
||||
this.genericType = genericType;
|
||||
this.genericType = new WeakReference<Type>(genericType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,9 +162,9 @@ public class DataTypeImpl<L> implements DataType<L> {
|
|||
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.get().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.get().hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -181,20 +182,20 @@ public class DataTypeImpl<L> implements DataType<L> {
|
|||
return false;
|
||||
} else if (!dataBinding.equals(other.dataBinding))
|
||||
return false;
|
||||
if (genericType == null) {
|
||||
if (genericType == null || genericType.get() == null) {
|
||||
if (other.genericType != 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 (physical == null || physical.get() == null) {
|
||||
if (other.physical != null)
|
||||
return false;
|
||||
} else if (!physical.equals(other.physical))
|
||||
} else if (!physical.get().equals(other.physical.get()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -219,8 +220,8 @@ public class DataTypeImpl<L> implements DataType<L> {
|
|||
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.get()) );
|
||||
b.append( ", physical=" + ((physical==null || physical.get()==null) ? "null" : physical.get()) );
|
||||
b.append( ", logical=" + ((logical==null) ? "null" : logical) );
|
||||
b.append( ", metaData size=" + ((metaDataMap==null) ? "0" : metaDataMap.size()) );
|
||||
b.append( "]" );
|
||||
|
|
Loading…
Reference in a new issue