// Magic JNI export that classes can use for redefining classes. // To use classes should declare this as a native function with signature (Ljava/lang/Class;[B[B)V extern"C" JNIEXPORT void JNICALL Java_art_Redefinition_doCommonClassRedefinition(
JNIEnv* env, jclass, jclass target, jbyteArray class_file_bytes, jbyteArray dex_file_bytes) {
DoClassRedefine<RedefineType::kNormal>(jvmti_env, env, target, class_file_bytes, dex_file_bytes);
}
// Magic JNI export that classes can use for redefining classes. // To use classes should declare this as a native function with signature // ([Ljava/lang/Class;[[B[[B)V extern"C" JNIEXPORT void JNICALL Java_art_Redefinition_doCommonMultiStructuralClassRedefinition(
JNIEnv* env,
jclass,
jobjectArray targets,
jobjectArray dex_file_bytes) {
std::vector<jclass> classes;
std::vector<jbyteArray> class_files;
std::vector<jbyteArray> dex_files;
jint len = env->GetArrayLength(targets); if (len != env->GetArrayLength(dex_file_bytes)) {
env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), "the three array arguments passed to this function have different lengths!"); return;
} for (jint i = 0; i < len; i++) {
classes.push_back(static_cast<jclass>(env->GetObjectArrayElement(targets, i)));
dex_files.push_back(static_cast<jbyteArray>(env->GetObjectArrayElement(dex_file_bytes, i)));
class_files.push_back(nullptr);
} return DoMultiClassRedefine<RedefineType::kStructural>(jvmti_env,
env,
len,
classes.data(),
class_files.data(),
dex_files.data());
}
// Magic JNI export that classes can use for redefining classes. // To use classes should declare this as a native function with signature // ([Ljava/lang/Class;[[B[[B)V extern"C" JNIEXPORT void JNICALL Java_art_Redefinition_doCommonMultiClassRedefinition(
JNIEnv* env,
jclass,
jobjectArray targets,
jobjectArray class_file_bytes,
jobjectArray dex_file_bytes) {
std::vector<jclass> classes;
std::vector<jbyteArray> class_files;
std::vector<jbyteArray> dex_files;
jint len = env->GetArrayLength(targets); if (len != env->GetArrayLength(class_file_bytes) || len != env->GetArrayLength(dex_file_bytes)) {
env->ThrowNew(env->FindClass("java/lang/IllegalArgumentException"), "the three array arguments passed to this function have different lengths!"); return;
} for (jint i = 0; i < len; i++) {
classes.push_back(static_cast<jclass>(env->GetObjectArrayElement(targets, i)));
dex_files.push_back(static_cast<jbyteArray>(env->GetObjectArrayElement(dex_file_bytes, i)));
class_files.push_back(static_cast<jbyteArray>(env->GetObjectArrayElement(class_file_bytes, i)));
} return DoMultiClassRedefine<RedefineType::kNormal>(jvmti_env,
env,
len,
classes.data(),
class_files.data(),
dex_files.data());
}
// Get all capabilities except those related to retransformation.
jint OnLoad(JavaVM* vm,
[[maybe_unused]] char* options,
[[maybe_unused]] void* reserved) { if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), JVMTI_VERSION_1_0)) {
printf("Unable to get jvmti env!\n"); return1;
}
SetupCommonRedefine(); return0;
}
// Map from class name to transformation result.
std::map<std::string, std::deque<CommonTransformationResult>> gTransformations; bool gPopTransformations = true;
staticvoid DoClassRetransformation(jvmtiEnv* jvmti_env, JNIEnv* env, jobjectArray targets) {
std::vector<jclass> classes;
jint len = env->GetArrayLength(targets);
classes.reserve(len); for (jint i = 0; i < len; i++) {
classes.push_back(static_cast<jclass>(env->GetObjectArrayElement(targets, i)));
}
jvmtiError res = jvmti_env->RetransformClasses(len, classes.data()); if (res != JVMTI_ERROR_NONE) {
throwRetransformationError(jvmti_env, env, len, classes.data(), res);
}
}
extern"C" JNIEXPORT void JNICALL Java_art_Redefinition_doCommonClassRetransformation(
JNIEnv* env, jclass, jobjectArray targets) {
jvmtiCapabilities caps;
jvmtiError caps_err = jvmti_env->GetCapabilities(&caps); if (caps_err != JVMTI_ERROR_NONE) {
env->ThrowNew(env->FindClass("java/lang/Exception"), "Unable to get current jvmtiEnv capabilities"); return;
}
// Allocate a new environment if we don't have the can_retransform_classes capability needed to // call the RetransformClasses function.
jvmtiEnv* real_env = nullptr; if (caps.can_retransform_classes != 1) {
JavaVM* vm = nullptr; if (env->GetJavaVM(&vm) != 0 ||
vm->GetEnv(reinterpret_cast<void**>(&real_env), JVMTI_VERSION_1_0) != 0) {
env->ThrowNew(env->FindClass("java/lang/Exception"), "Unable to create temporary jvmtiEnv for RetransformClasses call."); return;
}
SetStandardCapabilities(real_env);
} else {
real_env = jvmti_env;
}
DoClassRetransformation(real_env, env, targets); if (caps.can_retransform_classes != 1) {
real_env->DisposeEnvironment();
}
}
// Get all capabilities except those related to retransformation.
jint OnLoad(JavaVM* vm,
[[maybe_unused]] char* options,
[[maybe_unused]] void* reserved) { if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), JVMTI_VERSION_1_0)) {
printf("Unable to get jvmti env!\n"); return1;
}
SetupCommonRetransform(RedefineType::kNormal); return0;
}
} // namespace common_retransform
namespace common_transform {
// Get all capabilities except those related to retransformation.
jint OnLoad(JavaVM* vm,
[[maybe_unused]] char* options,
[[maybe_unused]] void* reserved) { if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), JVMTI_VERSION_1_0)) {
printf("Unable to get jvmti env!\n"); return1;
}
SetupCommonTransform(); return0;
}
staticvoid SetupCommonTransform() { // Don't set the retransform caps
jvmtiCapabilities caps = GetStandardCapabilities();
caps.can_retransform_classes = 0;
caps.can_retransform_any_class = 0;
jvmti_env->AddCapabilities(&caps);
// Use the same callback as the retransform test.
current_callbacks.ClassFileLoadHook = common_retransform::CommonClassFileLoadHookRetransformable;
jvmtiError res = jvmti_env->SetEventCallbacks(¤t_callbacks, sizeof(current_callbacks));
CHECK_EQ(res, JVMTI_ERROR_NONE);
common_retransform::gTransformations.clear();
}
} // namespace art
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.