Search in sources :

Example 1 with ReloadException

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;
}
Also used : Field(java.lang.reflect.Field) ReloadableType(org.springsource.loaded.ReloadableType) ReloadException(org.springsource.loaded.ReloadException) TypeRegistry(org.springsource.loaded.TypeRegistry) ReloadException(org.springsource.loaded.ReloadException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Aggregations

Field (java.lang.reflect.Field)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 ReloadException (org.springsource.loaded.ReloadException)1 ReloadableType (org.springsource.loaded.ReloadableType)1 TypeRegistry (org.springsource.loaded.TypeRegistry)1