--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java Tue Mar 03 12:30:48 2015 +0100
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java Tue Mar 03 06:23:50 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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
@@ -282,6 +282,7 @@
* implemented interface
*/
ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType();
+
if (!declType.isAssignableFrom(this)) {
throw new IllegalArgumentException("Invalid method");
}
@@ -311,7 +312,7 @@
/*
* For nonvirtual invokes, method must have a body
*/
- if ((options & INVOKE_NONVIRTUAL) != 0) {
+ if (isNonVirtual(options)) {
if (method.isAbstract()) {
throw new IllegalArgumentException("Abstract method");
}
@@ -323,7 +324,7 @@
* method argument types.
*/
ClassTypeImpl invokedClass;
- if ((options & INVOKE_NONVIRTUAL) != 0) {
+ if (isNonVirtual(options)) {
// No overrides in non-virtual invokes
invokedClass = clazz;
} else {
@@ -348,7 +349,7 @@
/*
* Only default methods allowed for nonvirtual invokes
*/
- if (!method.isDefault()) {
+ if (isNonVirtual(options) && !method.isDefault()) {
throw new IllegalArgumentException("Not a default method");
}
}
@@ -383,6 +384,7 @@
IncompatibleThreadStateException,
InvocationException,
ClassNotLoadedException {
+
validateMirror(threadIntf);
validateMirror(methodIntf);
validateMirrorsOrNulls(origArguments);
@@ -624,4 +626,8 @@
byte typeValueKey() {
return JDWP.Tag.OBJECT;
}
+
+ private static boolean isNonVirtual(int options) {
+ return (options & INVOKE_NONVIRTUAL) != 0;
+ }
}
--- a/jdk/test/com/sun/jdi/InterfaceMethodsTest.java Tue Mar 03 12:30:48 2015 +0100
+++ b/jdk/test/com/sun/jdi/InterfaceMethodsTest.java Tue Mar 03 06:23:50 2015 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, 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
@@ -24,6 +24,7 @@
/**
* @test
* @bug 8031195
+ * @bug 8071657
* @summary JDI: Add support for static and default methods in interfaces
*
* @run build TestScaffold VMConnection TargetListener TargetAdapter
@@ -38,6 +39,7 @@
private static final int RESULT_A = 1;
private static final int RESULT_B = 1;
private static final int RESULT_TARGET = 1;
+
static interface InterfaceA {
static int staticMethodA() {
System.out.println("-InterfaceA: static interface method A-");
@@ -202,6 +204,9 @@
// try to invoke static method B on the instance
testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
+
+ // try to invoke a virtual method
+ testInvokePos(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_A), true);
}
private void testInterfaceB(ObjectReference ref) {
@@ -302,9 +307,14 @@
private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value) {
+ testInvokePos(targetClass, ref, methodName, methodSig, value, false);
+ }
+
+ private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
+ String methodSig, Value value, boolean virtual) {
logInvocation(ref, methodName, methodSig, targetClass);
try {
- invoke(targetClass, ref, methodName, methodSig, value);
+ invoke(targetClass, ref, methodName, methodSig, value, virtual);
System.err.println("--- PASSED");
} catch (Exception e) {
System.err.println("--- FAILED");
@@ -314,9 +324,14 @@
private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
String methodSig, Value value, String msg) {
+ testInvokeNeg(targetClass, ref, methodName, methodSig, value, msg, false);
+ }
+
+ private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
+ String methodSig, Value value, String msg, boolean virtual) {
logInvocation(ref, methodName, methodSig, targetClass);
try {
- invoke(targetClass, ref, methodName, methodSig, value);
+ invoke(targetClass, ref, methodName, methodSig, value, virtual);
System.err.println("--- FAILED");
failure("FAILED: " + msg);
} catch (Exception e) {
@@ -326,7 +341,7 @@
}
private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName,
- String methodSig, Value value)
+ String methodSig, Value value, boolean virtual)
throws Exception {
Method method = getMethod(targetClass, methodName, methodSig);
if (method == null) {
@@ -334,10 +349,15 @@
}
println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method);
+ println(method.declaringType().toString());
Value returnValue = null;
if (ref != null) {
- returnValue = invokeInstance(ref, method);
+ if (virtual) {
+ returnValue = invokeVirtual(ref, method);
+ } else {
+ returnValue = invokeInstance(ref, method);
+ }
} else {
returnValue = invokeStatic(targetClass, method);
}
@@ -362,6 +382,10 @@
return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
}
+ private Value invokeVirtual(ObjectReference ref, Method method) throws Exception {
+ return ref.invokeMethod(mainThread, method, Collections.emptyList(), 0);
+ }
+
private Value invokeStatic(ReferenceType refType, Method method) throws Exception {
if (refType instanceof ClassType) {
return ((ClassType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);