Skip to content

Instantly share code, notes, and snippets.

@nickman
Created January 13, 2012 20:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickman/1608424 to your computer and use it in GitHub Desktop.
Save nickman/1608424 to your computer and use it in GitHub Desktop.
ClassFileTransformer for capturing GeneratedClosure byte code
/**
* {@inheritDoc}
* @see java.lang.instrument.ClassFileTransformer#transform(java.lang.ClassLoader, java.lang.String, java.lang.Class, java.security.ProtectionDomain, byte[])
*/
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
byte[] bytecode = classfileBuffer;
if(classBeingRedefined==null) {
if(loader instanceof GroovyClassLoader && isGeneratedClosure(bytecode)) {
put(className, loader, bytecode);
log.log("Class Load Stored [" , bytecode.length , "] Bytes for deferred class [" , className , "]");
}
} else {
if(GeneratedClosure.class.isAssignableFrom(classBeingRedefined)) {
put(classBeingRedefined, bytecode);
log.log("Class Retransform Stored [" , bytecode.length , "] Bytes for deferred class [" , className , "]");
}
}
return bytecode;
}
/**
* Determines if the passed bytecode represents a class that implements {@link GeneratedClosure}.
* @param bytecode The byte array
* @return true if the bytecode represents a class that implements {@link GeneratedClosure}, false otherwise.
*/
protected boolean isGeneratedClosure(byte[] bytecode) {
try {
for(String iface: new ClassReader(bytecode).getInterfaces()) {
if(generatedClosureName.equals(iface)) return true;
}
return false;
} catch (Exception e) {
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment