Permalink
1 comment
on commit
sign in to comment.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
8216324: GetClassMethods is confused by the presence of default metho…
…ds in super interfaces Backport-of: 277ec3d26080275e3c14b7e3f40c15e5cdfa3821
- Loading branch information
Showing
with
253 additions
and 47 deletions.
- +41 −41 src/hotspot/share/prims/jvmtiEnv.cpp
- +94 −0 test/hotspot/jtreg/serviceability/jvmti/GetClassMethods/OverpassMethods.java
- +103 −0 test/hotspot/jtreg/serviceability/jvmti/GetClassMethods/libOverpassMethods.cpp
- +7 −2 test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetClassMethods/getclmthd007.java
- +8 −4 test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetClassMethods/getclmthd007/getclmthd007.cpp
@@ -0,0 +1,94 @@ | ||
/* | ||
* Copyright (c) 2020, 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 | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
|
||
/** | ||
* @test | ||
* @bug 8216324 | ||
* @summary GetClassMethods is confused by the presence of default methods in super interfaces | ||
* @library /test/lib | ||
* @compile OverpassMethods.java | ||
* @run main/othervm/native -agentlib:OverpassMethods OverpassMethods | ||
* @run main/othervm/native -agentlib:OverpassMethods=maintain_original_method_order OverpassMethods | ||
*/ | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.Arrays; | ||
|
||
public class OverpassMethods { | ||
|
||
static { | ||
try { | ||
System.loadLibrary("OverpassMethods"); | ||
} catch (UnsatisfiedLinkError ex) { | ||
System.err.println("Could not load OverpassMethods library"); | ||
System.err.println("java.library.path:" + System.getProperty("java.library.path")); | ||
throw ex; | ||
} | ||
} | ||
|
||
static private void log(Object msg) { | ||
System.out.println(String.valueOf(msg)); | ||
} | ||
|
||
static private native Method[] getJVMTIDeclaredMethods(Class<?> klass); | ||
|
||
public interface Parent { | ||
default String def() { return "Parent.def"; } | ||
String method0(); | ||
String method1(); | ||
} | ||
|
||
public interface Child extends Parent { | ||
String method2(); | ||
} | ||
|
||
public static class Impl implements Child { | ||
public String method0() { return "Impl.method0"; } | ||
public String method1() { return "Impl.method1"; } | ||
public String method2() { return "Impl.method2"; } | ||
} | ||
|
||
public static void main(String[] args) { | ||
new Impl(); // To get classes initialized | ||
|
||
Method[] reflectMethods = Child.class.getDeclaredMethods(); | ||
Method[] jvmtiMethods = getJVMTIDeclaredMethods(Child.class); | ||
|
||
if (jvmtiMethods == null) { | ||
throw new RuntimeException("getJVMTIDeclaredMethods failed"); | ||
} | ||
|
||
log("Reflection getDeclaredMethods returned: " + Arrays.toString(reflectMethods)); | ||
log("JVMTI GetClassMethods returned: " + Arrays.toString(jvmtiMethods)); | ||
|
||
if (reflectMethods.length != jvmtiMethods.length) { | ||
throw new RuntimeException("OverpassMethods failed: Unexpected method count from JVMTI GetClassMethods!"); | ||
} | ||
if (!reflectMethods[0].equals(jvmtiMethods[0])) { | ||
throw new RuntimeException("OverpassMethods failed: Unexpected method from JVMTI GetClassMethods!"); | ||
} | ||
log("Test passed: Got expected output from JVMTI GetClassMethods!"); | ||
} | ||
} |
@@ -0,0 +1,103 @@ | ||
/* | ||
* Copyright (c) 2020, 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 | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include "jvmti.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#define ACC_STATIC 0x0008 | ||
|
||
static jvmtiEnv *jvmti = NULL; | ||
|
||
JNIEXPORT | ||
jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) { | ||
return JNI_VERSION_9; | ||
} | ||
|
||
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) { | ||
vm->GetEnv((void **)&jvmti, JVMTI_VERSION_11); | ||
|
||
if (options != NULL && strcmp(options, "maintain_original_method_order") == 0) { | ||
printf("Enabled capability: maintain_original_method_order\n"); | ||
jvmtiCapabilities caps = {}; | ||
caps.can_maintain_original_method_order = 1; | ||
|
||
jvmtiError err = jvmti->AddCapabilities(&caps); | ||
if (err != JVMTI_ERROR_NONE) { | ||
printf("Agent_OnLoad: AddCapabilities failed with error: %d\n", err); | ||
return JNI_ERR; | ||
} | ||
} | ||
return JNI_OK; | ||
} | ||
|
||
JNIEXPORT jobjectArray JNICALL Java_OverpassMethods_getJVMTIDeclaredMethods(JNIEnv *env, jclass static_klass, jclass klass) { | ||
jint method_count = 0; | ||
jmethodID* methods = NULL; | ||
jvmtiError err = jvmti->GetClassMethods(klass, &method_count, &methods); | ||
if (err != JVMTI_ERROR_NONE) { | ||
printf("GetClassMethods failed with error: %d\n", err); | ||
return NULL; | ||
} | ||
|
||
jclass method_cls = env->FindClass("java/lang/reflect/Method"); | ||
if (method_cls == NULL) { | ||
printf("FindClass (Method) failed\n"); | ||
return NULL; | ||
} | ||
jobjectArray array = env->NewObjectArray(method_count, method_cls, NULL); | ||
if (array == NULL) { | ||
printf("NewObjectArray failed\n"); | ||
return NULL; | ||
} | ||
|
||
for (int i = 0; i < method_count; i++) { | ||
jint modifiers = 0; | ||
err = jvmti->GetMethodModifiers(methods[i], &modifiers); | ||
if (err != JVMTI_ERROR_NONE) { | ||
printf("GetMethodModifiers failed with error: %d\n", err); | ||
return NULL; | ||
} | ||
|
||
jobject m = env->ToReflectedMethod(klass, methods[i], (modifiers & ACC_STATIC) == ACC_STATIC); | ||
if (array == NULL) { | ||
printf("ToReflectedMethod failed\n"); | ||
return NULL; | ||
} | ||
env->SetObjectArrayElement(array, i, m); | ||
|
||
env->DeleteLocalRef(m); | ||
} | ||
jvmti->Deallocate((unsigned char *)methods); | ||
|
||
return array; | ||
} | ||
#ifdef __cplusplus | ||
} | ||
#endif |
This comment has been minimized.
051ffce
Review
Issues