org.springsource.loaded
Class TypeRegistry

java.lang.Object
  extended by org.springsource.loaded.TypeRegistry

public class TypeRegistry
extends java.lang.Object

The type registry tracks all reloadable types loaded by a specific class loader. It is configurable via a springloaded.properties file (which it will discover as resources through the classloader) or directly via a configure(Properties) method call.

Since:
0.5.0

Field Summary
 boolean directlyDefineTypes
          Controls if the registry will define types or will allow the caller (possibly a transformer running under an agent) to define it.
 java.util.Map<java.lang.String,java.util.Set<ReloadableType>> jdkProxiesForInterface
           
static java.lang.String Key_ExcludedLoaders
           
static java.lang.String Key_Exclusions
           
static java.lang.String Key_Inclusions
           
static java.lang.String Key_Profile
           
static java.lang.String Key_ReloadableRebase
           
static int nextFreeRegistryId
           
static boolean nothingReloaded
           
 
Method Summary
 ReloadableType addType(java.lang.String dottedname, byte[] initialbytes)
          Add a type to the registry.
static java.lang.Object ccheck(int ids, java.lang.String descriptor)
           
 void checkChildClassLoader(ReloadableType currentlyDefining)
          To avoid leaking permgen we want to periodically discard the child classloader and recreate a new one.
 void configure(java.util.Properties properties)
          Configure this TypeRegistry using a specific set of properties - this will override any previous configuration.
 void ensureConfigured()
          Configure (if not already done) this TypeRegistry by locating springloaded.properties (through a findResources call) then loading it then processing any directives within it.
 void fireReloadEvent(ReloadableType reloadableType, java.lang.String versionsuffix)
           
 boolean fireUnableToReloadEvent(ReloadableType reloadableType, TypeDelta td, java.lang.String versionsuffix)
           
 ChildClassLoader getChildClassLoader()
           
 java.lang.Class<?> getClass_ClassInfo()
           
 java.lang.Class<?> getClass_GroovySystem()
           
 java.lang.ClassLoader getClassLoader()
           
 TypeDescriptor getDescriptorFor(java.lang.String slashedname)
           
 TypeDescriptor getDescriptorForReloadableType(java.lang.String slashedname)
          Only checks the reloadable types this registry knows about, it doesn't search beyond that.
 java.util.List<TypePattern> getExclusionPatterns()
           
 TypeDescriptorExtractor getExtractor()
           
 java.lang.reflect.Field getField_ClassInfo_cachedClassRef()
           
 int getId()
           
 java.util.List<TypePattern> getInclusionPatterns()
           
 java.util.Set<ReloadableType> getJDKProxiesFor(java.lang.String slashedInterfaceTypeName)
           
 TypeDescriptor getLatestDescriptorFor(java.lang.String slashedname)
           
 java.lang.reflect.Method getMethod_ClassInfo_getClassInfo()
           
 TypeRegistry getParentRegistry()
           
 java.util.Map<java.lang.String,java.lang.String> getRebasePaths()
           
 ReloadableType getReloadableSuperType(java.lang.String slashedClassname)
           
 ReloadableType getReloadableType(java.lang.Class<?> clazz)
           
 ReloadableType getReloadableType(int typeId)
           
static ReloadableType getReloadableType(int typeRegistryId, int typeId)
          This method discovers the reloadable type instance for the registry and type id specified.
 ReloadableType getReloadableType(java.lang.String slashedClassname)
          Determine the reloadabletype object representation for a specified class.
 ReloadableType getReloadableType(java.lang.String slashedClassname, boolean allocateIdIfNotYetLoaded)
          Find the ReloadableType object for a given classname.
 ReloadableType[] getReloadableTypes()
           
 int getTypeIdFor(java.lang.String slashname, boolean allocateIfNotFound)
          Lookup the type ID for a string.
static TypeRegistry getTypeRegistryFor(java.lang.ClassLoader classloader)
          Factory access method for obtaining TypeRegistry instances.
static boolean iincheck(int ids, java.lang.String nameAndDescriptor)
          Determine if something has changed in a particular type related to a particular descriptor and so the dispatcher interface should be used.
static boolean instanceFieldInterceptionRequired(int ids, java.lang.String name)
          Called for a field operation - trying to determine whether a particular field needs special handling.
static java.lang.Object invokespecialSearch(ReloadableType rt, java.lang.String nameAndDescriptor)
           
static __DynamicallyDispatchable ispcheck(int ids, java.lang.String nameAndDescriptor)
           
 boolean isReloadableTypeName(java.lang.String slashedName)
           
 boolean isReloadableTypeName(java.lang.String slashedName, java.security.ProtectionDomain protectionDomain, byte[] bytes)
          Determine if the type specified is a reloadable type.
 boolean isResolved(java.lang.Class<?> clazz)
           
static java.lang.Object istcheck(int ids, java.lang.String nameAndDescriptor)
          Determine if something has changed in a particular type related to a particular descriptor and so the dispatcher interface should be used.
static boolean ivicheck(int ids, java.lang.String nameAndDescriptor)
          Used in code the generated code replaces invokevirtual calls.
 void loadNewVersion(ReloadableType rtype, java.io.File file)
           
 byte[] methodCallRewrite(byte[] bytes)
          Rewrite the call sites in some class in the context of this registry (which knows about a particular set of types as being Reloadable).
 byte[] methodCallRewriteUseCacheIfAvailable(java.lang.String slashedClassName, byte[] bytes)
          This version will attempt to use a cache if one is being managed.
 void monitorForUpdates(ReloadableType rtype, java.lang.String externalForm)
           
static void reinitialize()
           
 void rememberReloadableType(int typeId, ReloadableType rtype)
          Sometimes we discover the reloadabletype during program execution, for example A calls B and we haven't yet seen B.
static void resetAllConfiguration()
           
 void resetConfiguration()
           
 void setShouldDefineClasses(boolean should)
           
 boolean shouldDefineClasses()
           
 boolean shouldRerunStaticInitializer(ReloadableType reloadableType, java.lang.String versionsuffix)
           
static boolean staticFieldInterceptionRequired(int ids, java.lang.String name)
          Called for a field operation - trying to determine whether a particular field needs special handling.
 java.lang.String toString()
           
static boolean typeRegistryExistsForId(int typeRegistryId)
          Check if a type registry exists for a specific type registry ID.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

nothingReloaded

public static boolean nothingReloaded

Key_ExcludedLoaders

public static final java.lang.String Key_ExcludedLoaders
See Also:
Constant Field Values

Key_Inclusions

public static final java.lang.String Key_Inclusions
See Also:
Constant Field Values

Key_Exclusions

public static final java.lang.String Key_Exclusions
See Also:
Constant Field Values

Key_ReloadableRebase

public static final java.lang.String Key_ReloadableRebase
See Also:
Constant Field Values

Key_Profile

public static final java.lang.String Key_Profile
See Also:
Constant Field Values

nextFreeRegistryId

public static int nextFreeRegistryId

directlyDefineTypes

public boolean directlyDefineTypes
Controls if the registry will define types or will allow the caller (possibly a transformer running under an agent) to define it.


jdkProxiesForInterface

public java.util.Map<java.lang.String,java.util.Set<ReloadableType>> jdkProxiesForInterface
Method Detail

reinitialize

public static void reinitialize()

typeRegistryExistsForId

public static boolean typeRegistryExistsForId(int typeRegistryId)
Check if a type registry exists for a specific type registry ID. Enables parts of the system (for example the FileSystemWatcher) to check if a type registry is still alive/active.

Parameters:
typeRegistryId - the ID of a type registry
Returns:
true if that type registry is still around, false otherwise

getTypeRegistryFor

public static TypeRegistry getTypeRegistryFor(java.lang.ClassLoader classloader)
Factory access method for obtaining TypeRegistry instances. Returns a TypeRegistry for the specified classloader.


getDescriptorForReloadableType

public TypeDescriptor getDescriptorForReloadableType(java.lang.String slashedname)
Only checks the reloadable types this registry knows about, it doesn't search beyond that.


getDescriptorFor

public TypeDescriptor getDescriptorFor(java.lang.String slashedname)

getLatestDescriptorFor

public TypeDescriptor getLatestDescriptorFor(java.lang.String slashedname)

ensureConfigured

public void ensureConfigured()
Configure (if not already done) this TypeRegistry by locating springloaded.properties (through a findResources call) then loading it then processing any directives within it.


configure

public void configure(java.util.Properties properties)
Configure this TypeRegistry using a specific set of properties - this will override any previous configuration. It is mainly provided for testing purposes.

Parameters:
properties - the properties to use to configure this type registry

resetConfiguration

public void resetConfiguration()

resetAllConfiguration

public static void resetAllConfiguration()

getInclusionPatterns

public java.util.List<TypePattern> getInclusionPatterns()

getExclusionPatterns

public java.util.List<TypePattern> getExclusionPatterns()

isReloadableTypeName

public boolean isReloadableTypeName(java.lang.String slashedName)

isReloadableTypeName

public boolean isReloadableTypeName(java.lang.String slashedName,
                                    java.security.ProtectionDomain protectionDomain,
                                    byte[] bytes)
Determine if the type specified is a reloadable type. This method works purely by name, it does not load anything.

Parameters:
slashedName - the type name, eg. a/b/c/D
Returns:
true if the type is reloadable, false otherwise

getTypeIdFor

public int getTypeIdFor(java.lang.String slashname,
                        boolean allocateIfNotFound)
Lookup the type ID for a string. First checks those allocated but not yet registered, then those that are already registered. If not found then a new one is allocated and recorded.

Parameters:
slashname - the slashed type name, eg. a/b/c/D
allocateIfNotFound - determines whether an id should be allocated for the type if it cannot be found
Returns:
the unique ID number

methodCallRewrite

public byte[] methodCallRewrite(byte[] bytes)
Rewrite the call sites in some class in the context of this registry (which knows about a particular set of types as being Reloadable).


methodCallRewriteUseCacheIfAvailable

public byte[] methodCallRewriteUseCacheIfAvailable(java.lang.String slashedClassName,
                                                   byte[] bytes)
This version will attempt to use a cache if one is being managed.


loadNewVersion

public void loadNewVersion(ReloadableType rtype,
                           java.io.File file)

getClassLoader

public java.lang.ClassLoader getClassLoader()
Returns:
the classloader associated with this registry, the caller should not cache it.

getId

public int getId()
Returns:
the ID number of this type registry (that was allocated on creation)

addType

public ReloadableType addType(java.lang.String dottedname,
                              byte[] initialbytes)
Add a type to the registry. The name should have already passed the isReloadableTypeName() test.

Parameters:
dottedtypename - type name of the form a.b.c.D
initialbytes - the first version of the bytes as loaded
Returns:
the ReloadableType or null if it cannot be made reloadable

getReloadableType

public ReloadableType getReloadableType(int typeId)

rememberReloadableType

public void rememberReloadableType(int typeId,
                                   ReloadableType rtype)
Sometimes we discover the reloadabletype during program execution, for example A calls B and we haven't yet seen B. We find B has been loaded by a parent classloader, let's remember B here so we can do fast lookups for it.


getReloadableType

public ReloadableType getReloadableType(java.lang.String slashedClassname)
Determine the reloadabletype object representation for a specified class. If the caller already knows the ID for the type, that would be a quicker way to locate the reloadable type object.


getReloadableSuperType

public ReloadableType getReloadableSuperType(java.lang.String slashedClassname)

getReloadableType

public ReloadableType getReloadableType(java.lang.String slashedClassname,
                                        boolean allocateIdIfNotYetLoaded)
Find the ReloadableType object for a given classname. If the allocateIdIfNotYetLoaded option is set then a new id will be allocated for this classname if it hasn't previously been seen before. This method does not create new ReloadableType objects, they are expected to come into existence when defined by the classloader.

Parameters:
slashedClassname -
allocateIdIfNotYetLoaded -
Returns:

getExtractor

public TypeDescriptorExtractor getExtractor()

getRebasePaths

public java.util.Map<java.lang.String,java.lang.String> getRebasePaths()

shouldDefineClasses

public boolean shouldDefineClasses()

setShouldDefineClasses

public void setShouldDefineClasses(boolean should)

istcheck

public static java.lang.Object istcheck(int ids,
                                        java.lang.String nameAndDescriptor)
Determine if something has changed in a particular type related to a particular descriptor and so the dispatcher interface should be used. The type registry ID and class ID are merged in the 'ids' parameter. This method is for INVOKESTATIC rewrites and so performs additional checks because it assumes the target is static.


invokespecialSearch

public static java.lang.Object invokespecialSearch(ReloadableType rt,
                                                   java.lang.String nameAndDescriptor)

ispcheck

public static __DynamicallyDispatchable ispcheck(int ids,
                                                 java.lang.String nameAndDescriptor)

ccheck

public static java.lang.Object ccheck(int ids,
                                      java.lang.String descriptor)

iincheck

public static boolean iincheck(int ids,
                               java.lang.String nameAndDescriptor)
Determine if something has changed in a particular type related to a particular descriptor and so the dispatcher interface should be used. The type registry ID and class ID are merged in the 'ids' parameter. This method is for INVOKEINTERFACE rewrites and so performs additional checks because it assumes the target is an interface.

Methods on interfaces cannot really 'change' - the visibility is always public and they are never static. This means everything that the descriptor embodies everything about a method interface. Therefore, if something changes about the descriptor it is considered an entirely different method (and the old form is a deleted method). For this reason there is no need to consider 'changed' methods, because the static-ness nor visibility cannot change.


instanceFieldInterceptionRequired

public static boolean instanceFieldInterceptionRequired(int ids,
                                                        java.lang.String name)
Called for a field operation - trying to determine whether a particular field needs special handling.


staticFieldInterceptionRequired

public static boolean staticFieldInterceptionRequired(int ids,
                                                      java.lang.String name)
Called for a field operation - trying to determine whether a particular field needs special handling.


ivicheck

public static boolean ivicheck(int ids,
                               java.lang.String nameAndDescriptor)
Used in code the generated code replaces invokevirtual calls. Determine if the code can run as it was originally compiled. This method will return FALSE if nothing has changed to interfere with the invocation and it should proceed. This method will return TRUE if something has changed and the caller needs to do something different.


getReloadableType

public static ReloadableType getReloadableType(int typeRegistryId,
                                               int typeId)
This method discovers the reloadable type instance for the registry and type id specified.


toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

monitorForUpdates

public void monitorForUpdates(ReloadableType rtype,
                              java.lang.String externalForm)

shouldRerunStaticInitializer

public boolean shouldRerunStaticInitializer(ReloadableType reloadableType,
                                            java.lang.String versionsuffix)

fireReloadEvent

public void fireReloadEvent(ReloadableType reloadableType,
                            java.lang.String versionsuffix)

fireUnableToReloadEvent

public boolean fireUnableToReloadEvent(ReloadableType reloadableType,
                                       TypeDelta td,
                                       java.lang.String versionsuffix)

getClass_GroovySystem

public java.lang.Class<?> getClass_GroovySystem()

getClass_ClassInfo

public java.lang.Class<?> getClass_ClassInfo()

getMethod_ClassInfo_getClassInfo

public java.lang.reflect.Method getMethod_ClassInfo_getClassInfo()

getField_ClassInfo_cachedClassRef

public java.lang.reflect.Field getField_ClassInfo_cachedClassRef()

checkChildClassLoader

public void checkChildClassLoader(ReloadableType currentlyDefining)
To avoid leaking permgen we want to periodically discard the child classloader and recreate a new one. We will need to then redefine types again over time as they are used (the most recent variants of them).


getChildClassLoader

public ChildClassLoader getChildClassLoader()

isResolved

public boolean isResolved(java.lang.Class<?> clazz)

getReloadableType

public ReloadableType getReloadableType(java.lang.Class<?> clazz)

getParentRegistry

public TypeRegistry getParentRegistry()

getReloadableTypes

public ReloadableType[] getReloadableTypes()

getJDKProxiesFor

public java.util.Set<ReloadableType> getJDKProxiesFor(java.lang.String slashedInterfaceTypeName)