Skip to content

Instantly share code, notes, and snippets.

@abelaska
Created May 28, 2020 07:19
Show Gist options
  • Save abelaska/aeb8b5ae57034399d79a82852a21b6ba to your computer and use it in GitHub Desktop.
Save abelaska/aeb8b5ae57034399d79a82852a21b6ba to your computer and use it in GitHub Desktop.
Annotate classes at runtime with ByteBuddy
// add @JsonDeserialize(using = JsonDeserializer.None.class) to classes
// inspired by https://stackoverflow.com/a/49320259/1638047
@SneakyThrows
Class<? extends ManagementResource> annotateResourceClass(Class<? extends ManagementResource> clazz) {
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.get(clazz.getName());
if (ctClass.isFrozen()) {
return clazz;
}
ClassFile classFile = ctClass.getClassFile();
ConstPool constPool = classFile.getConstPool();
final String annotationAttr = AnnotationsAttribute.visibleTag;
final AnnotationsAttribute attr = Optional.ofNullable((AnnotationsAttribute) classFile.getAttribute(annotationAttr))
.orElse(new AnnotationsAttribute(constPool, annotationAttr));
// do not re-create annotation if already attached to the class
final String annotationClassName = JsonDeserialize.class.getName();
final Annotation annotation = Optional.ofNullable(attr.getAnnotation(annotationClassName))
.orElse(new Annotation(annotationClassName, constPool));
annotation.addMemberValue("using", new ClassMemberValue(JsonDeserializer.None.class.getName(), constPool));
attr.addAnnotation(annotation);
classFile.addAttribute(attr);
final byte[] byteCode = ctClass.toBytecode();
final String target = clazz.getName().replace('.', '/');
final ClassFileTransformer cft = new ClassFileTransformer() {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) {
if (target.equals(className)) {
return byteCode;
}
return null;
}
};
try {
instrumentation.addTransformer(cft, true);
instrumentation.retransformClasses(clazz);
} finally {
instrumentation.removeTransformer(cft);
}
return clazz;
}
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
<version>3.25.0-GA</version>
</dependency>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment