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 ; }
Access and return the ReloadableType field on a specified class .