-
-
Notifications
You must be signed in to change notification settings - Fork 808
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to remove/replace existing annotations? #917
Comments
Thanks, glad you like it. Member removal is unfortunately not supported overly well. You'd need to register a |
With your suggestion and the below code, using
|
So, if you wanted to avoid the visitor, you can set Alternatively, you'd need to drop the first annotation of that type being visited. Byte Buddy always plays the preexisting annotations down the visitor chain first. |
I was able to replace the annotation value of the existing annotation on a method by using an The below works, but is it the right way to do using an
|
Yes, absolutely. If your replacement is that simple, then using ASM is the best option! |
Thank you so much for your help. |
The transformer can be added in the Byte Buddy should really offer a convenience DSL here to make these removals simple. I'll leave this ticket open as an enhancement for a future version. |
Hi, checking in to see if this feature is since available in bytebuddy? Basically i am trying to replace class level annotation - and I wrote custom AsmVisitorWrapper following notes above -
I was expecting this would remove initial annotation at class level and then create new one - however this complains of duplicate annotation - possibly the initial annotation isn't getting removed. Secondly, I tried to change the annotation inside visitAnnotation method but could'nt find API to do so. any pointers are much appreciated. Thank you. |
Try disabling annotation retention: https://github.com/raphw/byte-buddy/blob/master/byte-buddy-dep/src/main/java/net/bytebuddy/implementation/attribute/AnnotationRetention.java#L34 Otherwise, Byte Buddy copies the original annotation to retain the definition of default values compared to explicitly set defaults. |
i tried using that as well - I hope this is the way to do it. thank you
Logs:
|
Indeed, the problem happens in validation which is not aware of the visitor. Configure |
Thank you @raphw .
and in logs -
I will spend some more time on it and share findings. Thanks for your help as always. |
Yes, the visitor you implemented removes all annotations of the given type, if you added them or if they were added previously. The preexisting annotations will be visisted first, you could therefore add a counter to avoid this. |
thank you @raphw. I was able to make some progress with your inputs. |
Since this issue provided much of the inspiration, here is the visitor I needed to write to parse "most" annotations in a class, possibly amending them with a private AsmVisitorWrapper rewriteAnnotations(Remapper remapper) {
// Complicated looking code constructs a hierarchical Visitor that finds @annotations and checks their values
return new AsmVisitorWrapper() {
@Override
public int mergeWriter(int flags) {
return flags;
}
@Override
public int mergeReader(int flags) {
return flags;
}
@Override
public ClassVisitor wrap(TypeDescription instrumentedType, ClassVisitor classVisitor,
Context implementationContext, TypePool typePool, FieldList<InDefinedShape> fields,
MethodList<?> methods, int writerFlags, int readerFlags) {
return new ClassVisitor(ASM9, classVisitor) {
@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return new AnnotationRemapper( // class annotations
descriptor,
super.visitAnnotation(descriptor, visible),
remapper);
}
@Override
public FieldVisitor visitField(int access, String name, String descriptor,
String signature, Object value) {
FieldVisitor delegate = super.visitField(access, name, descriptor, signature,
value);
return new FieldVisitor(ASM9, delegate) {
@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return new AnnotationRemapper( // field annotations
descriptor,
super.visitAnnotation(descriptor, visible),
remapper);
}
};
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor,
String signature, String[] exceptions) {
MethodVisitor delegate = super.visitMethod(access, name, descriptor, signature,
exceptions);
return new MethodVisitor(ASM9, delegate) {
@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
return new AnnotationRemapper( // method annotations
descriptor,
super.visitAnnotation(descriptor, visible),
remapper);
}
@Override
public AnnotationVisitor visitParameterAnnotation(int parameter,
String descriptor, boolean visible) { // method-parameter annotations
return new AnnotationRemapper(
descriptor,
super.visitParameterAnnotation(parameter, descriptor, visible),
remapper);
}
};
}
};
}
};
} |
Thank you for this wonderful library. However, I am stuck at one point. I am able to add annotations to a field/method, but not able to replace or remove existing annotation.
I have the following requirement, on a method,
I would like to,
@OneToOne (fetch = FetchType.LAZY)
@OneToOne (fetch = FetchType.EAGER)
I am using the bytebuddy maven plugin, using the
DynamicType.Builder
tovisit
the method to add new annotation usingMemberAttributeExtension.ForMethod().annotateMethod()
, but not sure how to remove or replace existing annotations.I tried using
MemberSubstitution
, but did not get that to work for removing / replacing annotationsFor your help I will be immensely grateful.
The text was updated successfully, but these errors were encountered: