Created
May 28, 2020 07:19
-
-
Save abelaska/aeb8b5ae57034399d79a82852a21b6ba to your computer and use it in GitHub Desktop.
Annotate classes at runtime with ByteBuddy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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