use of org.springsource.loaded.ReloadException in project spring-loaded by spring-projects.
the class ReflectiveInterceptor method getRType.
/**
* Access and return the ReloadableType field on a specified class.
*
* @param clazz the class for which to discover the reloadable type
* @return the reloadable type for the class, or null if not reloadable
*/
public static ReloadableType getRType(Class<?> clazz) {
// ReloadableType rtype = null;
WeakReference<ReloadableType> ref = classToRType.get(clazz);
ReloadableType rtype = null;
if (ref != null) {
rtype = ref.get();
}
if (rtype == null) {
if (!theOldWay) {
// 'theOldWay' attempts to grab the field from the type via reflection. This usually works except
// in cases where the class is not resolved yet since it can cause the class to resolve and its
// static initializer to run. This was happening on a grails compile where the compiler is
// loading dependencies (but not initializing them). Instead we can use this route of
// discovering the type registry and locating the reloadable type. This does some map lookups
// which may be a problem, but once discovered, it is cached in the weak ref so that shouldn't
// be an ongoing perf problem.
// TODO testcases for something that is reloaded without having been resolved
ClassLoader cl = clazz.getClassLoader();
TypeRegistry tr = TypeRegistry.getTypeRegistryFor(cl);
if (tr == null) {
classToRType.put(clazz, ReloadableType.NOT_RELOADABLE_TYPE_REF);
} else {
rtype = tr.getReloadableType(clazz.getName().replace('.', '/'));
if (rtype == null) {
classToRType.put(clazz, ReloadableType.NOT_RELOADABLE_TYPE_REF);
} else {
classToRType.put(clazz, new WeakReference<ReloadableType>(rtype));
}
}
} else {
// need to work it out
Field rtypeField;
try {
// System.out.println("discovering field for " + clazz.getName());
// TODO cache somewhere - will need a clazz>Field cache
rtypeField = clazz.getDeclaredField(Constants.fReloadableTypeFieldName);
} catch (NoSuchFieldException nsfe) {
classToRType.put(clazz, ReloadableType.NOT_RELOADABLE_TYPE_REF);
// expensive if constantly discovering this
return null;
}
try {
rtypeField.setAccessible(true);
rtype = (ReloadableType) rtypeField.get(null);
if (rtype == null) {
classToRType.put(clazz, ReloadableType.NOT_RELOADABLE_TYPE_REF);
throw new ReloadException("ReloadableType field '" + Constants.fReloadableTypeFieldName + "' is 'null' on type " + clazz.getName());
} else {
classToRType.put(clazz, new WeakReference<ReloadableType>(rtype));
}
} catch (Exception e) {
throw new ReloadException("Unable to access ReloadableType field '" + Constants.fReloadableTypeFieldName + "' on type " + clazz.getName(), e);
}
}
} else if (rtype == ReloadableType.NOT_RELOADABLE_TYPE) {
return null;
}
return rtype;
}
Aggregations