8328137: PreserveAllAnnotations can cause failure of class retransformation

Reviewed-by: coleenp, sspitsyn
This commit is contained in:
Alex Menkov 2024-04-03 00:23:36 +00:00
parent 021ed6aea9
commit f88f31dcbf
3 changed files with 33 additions and 11 deletions

View File

@ -119,10 +119,10 @@ void JvmtiClassFileReconstituter::write_field_infos() {
write_signature_attribute(generic_signature_index);
}
if (anno != nullptr) {
write_annotations_attribute("RuntimeVisibleAnnotations", anno);
write_annotations_attribute("RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", anno);
}
if (type_anno != nullptr) {
write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
write_annotations_attribute("RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", type_anno);
}
}
}
@ -380,6 +380,20 @@ void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_n
memcpy(writeable_address(length), annos->adr_at(0), length);
}
void JvmtiClassFileReconstituter::write_annotations_attribute(const char* attr_name,
const char* fallback_attr_name,
AnnotationArray* annos) {
TempNewSymbol sym = SymbolTable::probe(attr_name, (int)strlen(attr_name));
if (sym != nullptr) {
if (symbol_to_cpool_index(sym) != 0) {
write_annotations_attribute(attr_name, annos);
return;
}
}
// use fallback name
write_annotations_attribute(fallback_attr_name, annos);
}
// BootstrapMethods_attribute {
// u2 attribute_name_index;
// u4 attribute_length;
@ -519,10 +533,10 @@ void JvmtiClassFileReconstituter::write_record_attribute() {
write_signature_attribute(component->generic_signature_index());
}
if (component->annotations() != nullptr) {
write_annotations_attribute("RuntimeVisibleAnnotations", component->annotations());
write_annotations_attribute("RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", component->annotations());
}
if (component->type_annotations() != nullptr) {
write_annotations_attribute("RuntimeVisibleTypeAnnotations", component->type_annotations());
write_annotations_attribute("RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", component->type_annotations());
}
}
}
@ -761,13 +775,13 @@ void JvmtiClassFileReconstituter::write_method_info(const methodHandle& method)
write_signature_attribute(generic_signature_index);
}
if (anno != nullptr) {
write_annotations_attribute("RuntimeVisibleAnnotations", anno);
write_annotations_attribute("RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", anno);
}
if (param_anno != nullptr) {
write_annotations_attribute("RuntimeVisibleParameterAnnotations", param_anno);
write_annotations_attribute("RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations", param_anno);
}
if (type_anno != nullptr) {
write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
write_annotations_attribute("RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", type_anno);
}
}
@ -827,10 +841,10 @@ void JvmtiClassFileReconstituter::write_class_attributes() {
write_source_debug_extension_attribute();
}
if (anno != nullptr) {
write_annotations_attribute("RuntimeVisibleAnnotations", anno);
write_annotations_attribute("RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", anno);
}
if (type_anno != nullptr) {
write_annotations_attribute("RuntimeVisibleTypeAnnotations", type_anno);
write_annotations_attribute("RuntimeVisibleTypeAnnotations", "RuntimeInvisibleTypeAnnotations", type_anno);
}
if (ik()->nest_host_index() != 0) {
write_nest_host_attribute();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -117,6 +117,13 @@ class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter {
void write_signature_attribute(u2 generic_signaure_index);
void write_attribute_name_index(const char* name);
void write_annotations_attribute(const char* attr_name, AnnotationArray* annos);
// With PreserveAllAnnotations option "runtime invisible" annotations
// (RuntimeInvisibleAnnotations/RuntimeInvisibleTypeAnnotations/RuntimeInvisibleParameterAnnotations)
// are considered "runtime visible" and ClassFileReconstituter writes them as
// RuntimeVisibleAnnotations/RuntimeVisibleTypeAnnotations/RuntimeVisibleParameterAnnotations.
// This helper method is for the corner case when "runtime visible" attribute name is not presents
// in the class constant pool and the annotations are written with fallback "runtime invisible" name.
void write_annotations_attribute(const char* attr_name, const char* fallback_attr_name, AnnotationArray* annos);
void write_bootstrapmethod_attribute();
void write_nest_host_attribute();
void write_nest_members_attribute();

View File

@ -23,12 +23,13 @@
/*
* @test
* @bug 8315575
* @bug 8315575 8328137
* @summary test that records with invisible annotation can be retransformed
*
* @library /test/lib
* @run shell MakeJAR.sh retransformAgent
* @run main/othervm -javaagent:retransformAgent.jar -Xlog:redefine+class=trace RetransformRecordAnnotation
* @run main/othervm -javaagent:retransformAgent.jar -XX:+PreserveAllAnnotations -Xlog:redefine+class=trace RetransformRecordAnnotation
*/
import java.io.File;