Merge "JDWP Tests: add breakpoint tests for framework code"
diff --git a/jdwp/Android.mk b/jdwp/Android.mk
index 00449da..8a5bce4 100644
--- a/jdwp/Android.mk
+++ b/jdwp/Android.mk
@@ -36,6 +36,7 @@
LOCAL_NO_EMMA_COMPILE := true
LOCAL_CTS_TEST_PACKAGE := android.jdwp
LOCAL_CTS_TARGET_RUNTIME_ARGS := $(cts_jdwp_test_target_runtime_args)
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
include $(BUILD_CTS_TARGET_JAVA_LIBRARY)
include $(CLEAR_VARS)
@@ -46,6 +47,7 @@
LOCAL_NO_EMMA_INSTRUMENT := true
LOCAL_NO_EMMA_COMPILE := true
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/jdwp
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
include $(BUILD_JAVA_LIBRARY)
include $(CLEAR_VARS)
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/framework/jdwp/JDWPCommands.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/framework/jdwp/JDWPCommands.java
index f2d5c25..14aa8d9 100644
--- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/framework/jdwp/JDWPCommands.java
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/framework/jdwp/JDWPCommands.java
@@ -157,6 +157,8 @@
*/
public class InterfaceTypeCommandSet {
public static final byte CommandSetID = 5;
+
+ public static final byte InvokeMethodCommand = 1;
}
/**
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/InterfaceType/InvokeMethodDebuggee.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/InterfaceType/InvokeMethodDebuggee.java
new file mode 100644
index 0000000..2e9f401
--- /dev/null
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/InterfaceType/InvokeMethodDebuggee.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.jpda.tests.jdwp.InterfaceType;
+
+import org.apache.harmony.jpda.tests.framework.LogWriter;
+import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
+import org.apache.harmony.jpda.tests.share.JPDATestOptions;
+import org.apache.harmony.jpda.tests.share.SyncDebuggee;
+
+/**
+ * Used for InterfaceType.InvokeMethodTest.testInvokeMethodStatic
+ */
+public class InvokeMethodDebuggee extends SyncDebuggee implements InvokeMethodTestInterface {
+
+ void execMethod() {
+ logWriter.println("InvokeMethodDebuggee.execMethod()");
+ }
+
+ @Override
+ public void run() {
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY);
+ logWriter.println("InvokeMethodDebuggee");
+ synchronizer.receiveMessageWithoutException(
+ "org.apache.harmony.jpda.tests.jdwp.InterfaceType.InvokeMethodDebuggee(#1)");
+ execMethod();
+ synchronizer.receiveMessageWithoutException(
+ "org.apache.harmony.jpda.tests.jdwp.InterfaceType.InvokeMethodDebuggee(#2)");
+ }
+ public static void main(String[] args) {
+ runDebuggee(InvokeMethodDebuggee.class);
+ }
+}
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/InterfaceType/InvokeMethodTest.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/InterfaceType/InvokeMethodTest.java
new file mode 100644
index 0000000..1301748
--- /dev/null
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/InterfaceType/InvokeMethodTest.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.jpda.tests.jdwp.InterfaceType;
+
+import org.apache.harmony.jpda.tests.framework.LogWriter;
+import org.apache.harmony.jpda.tests.framework.jdwp.*;
+import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
+import org.apache.harmony.jpda.tests.jdwp.share.debuggee.*;
+import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
+import org.apache.harmony.jpda.tests.share.JPDATestOptions;
+
+/**
+ * JDWP unit test to exercise InterfaceType.InvokeMethod command.
+ */
+public class InvokeMethodTest extends JDWPSyncTestCase {
+
+ @Override
+ protected String getDebuggeeClassName() {
+ return InvokeMethodDebuggee.class.getName();
+ }
+
+ /**
+ * This testcase exercises InterfaceType.InvokeMethod command.
+ * <BR>The test first starts the debuggee, request METHOD_ENTRY event so the
+ * application suspends on first invoke.
+ * <BR>Then sends InterfaceType.InvokeMethod command for method with null
+ * argument. Checks that returned value is expected int value and returned
+ * exception object is as expected.
+ * <BR>Finally resume the application.
+ */
+ private void testInvokeMethodStatic(boolean shouldThrow) {
+ synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
+
+ // Get debuggee class ID.
+ String debuggeeClassSig = getDebuggeeClassSignature();
+ long debuggeeTypeID = debuggeeWrapper.vmMirror.getClassID(debuggeeClassSig);
+ assertTrue("Failed to find debuggee class", debuggeeTypeID != 0);
+
+ // Set METHOD_ENTRY event request so application is suspended.
+ CommandPacket packet = new CommandPacket(
+ JDWPCommands.EventRequestCommandSet.CommandSetID,
+ JDWPCommands.EventRequestCommandSet.SetCommand);
+ packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
+ packet.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL);
+ packet.setNextValueAsInt(1); // number of modifiers.
+ packet.setNextValueAsByte(EventMod.ModKind.ClassOnly); // class-only modifier.
+ packet.setNextValueAsReferenceTypeID(debuggeeTypeID);
+ ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
+ checkReplyPacket(reply, "EventRequest::Set command");
+
+ int requestID = reply.getNextValueAsInt();
+ logWriter.println(" EventRequest.Set: requestID=" + requestID);
+ assertAllDataRead(reply);
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
+
+ long targetThreadID = 0;
+ // Wait for METHOD_ENTRY event and collect event thread.
+ CommandPacket event = debuggeeWrapper.vmMirror.receiveEvent();
+ byte suspendPolicy = event.getNextValueAsByte();
+ int events = event.getNextValueAsInt();
+ logWriter.println(" EVENT_THREAD event: suspendPolicy=" + suspendPolicy + " events=" + events);
+ for (int i = 0; i < events; i++) {
+ byte eventKind = event.getNextValueAsByte();
+ int newRequestID = event.getNextValueAsInt();
+ long threadID = event.getNextValueAsThreadID();
+ //Location location =
+ event.getNextValueAsLocation();
+ logWriter.println(" EVENT_THREAD event " + i + ": eventKind="
+ + eventKind + " requestID=" + newRequestID + " threadID="
+ + threadID);
+ if (newRequestID == requestID) {
+ targetThreadID = threadID;
+ }
+ }
+ assertAllDataRead(event);
+ assertTrue("Invalid targetThreadID, must be != 0", targetThreadID != 0);
+
+ // Now we're suspended, clear event request.
+ debuggeeWrapper.vmMirror.clearEvent(JDWPConstants.EventKind.METHOD_ENTRY, requestID);
+
+ // Get test method ID.
+ String debuggeeInterfaceSig = getClassSignature(InvokeMethodTestInterface.class);
+ long debuggeeInterfaceTypeID =
+ debuggeeWrapper.vmMirror.getInterfaceID(debuggeeInterfaceSig);
+ assertTrue("Failed to find debuggee interface", debuggeeInterfaceTypeID != 0);
+ long targetMethodID = debuggeeWrapper.vmMirror.getMethodID(debuggeeInterfaceTypeID,
+ "testInvokeMethodStatic1");
+ assertTrue("Failed to find method", targetMethodID != 0);
+
+ Value throwValue = new Value(shouldThrow);
+ // Invoke test method with null argument.
+ packet = new CommandPacket(
+ JDWPCommands.InterfaceTypeCommandSet.CommandSetID,
+ JDWPCommands.InterfaceTypeCommandSet.InvokeMethodCommand);
+ packet.setNextValueAsInterfaceID(debuggeeInterfaceTypeID);
+ packet.setNextValueAsThreadID(targetThreadID);
+ packet.setNextValueAsMethodID(targetMethodID);
+ packet.setNextValueAsInt(1); // number of arguments
+ packet.setNextValueAsValue(throwValue);
+ packet.setNextValueAsInt(0); // invoke options
+ logWriter.println(" Send InterfaceType.InvokeMethod " +
+ ((shouldThrow) ? "with" : "without") + " exception.");
+ reply = debuggeeWrapper.vmMirror.performCommand(packet);
+ checkReplyPacket(reply, "InterfaceType::InvokeMethod command");
+
+ Value returnValue = reply.getNextValueAsValue();
+ assertNotNull("Returned value is null", returnValue);
+ if (shouldThrow) {
+ assertEquals("Invalid returned value,", 0, returnValue.getIntValue());
+ logWriter.println(" InterfaceType.InvokeMethod: returnValue.getIntValue()="
+ + returnValue.getIntValue());
+
+ // Check that some exception was thrown.
+ TaggedObject exception = reply.getNextValueAsTaggedObject();
+ assertNotNull("Returned exception is null", exception);
+ assertTrue("Invalid exception object ID:<" + exception.objectID + ">",
+ exception.objectID != 0);
+ assertEquals("Invalid exception tag,", JDWPConstants.Tag.OBJECT_TAG, exception.tag
+ , JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG)
+ , JDWPConstants.Tag.getName(exception.tag));
+ logWriter.println(" InterfaceType.InvokeMethod: exception.tag="
+ + exception.tag + " exception.objectID=" + exception.objectID);
+ } else {
+ assertEquals("Invalid returned value,",
+ InvokeMethodTestInterface.RETURN_VALUE, returnValue.getIntValue());
+ logWriter.println(" InterfaceType.InvokeMethod: returnValue.getIntValue()="
+ + returnValue.getIntValue());
+
+ TaggedObject exception = reply.getNextValueAsTaggedObject();
+ assertNotNull("Returned exception is null", exception);
+ assertEquals("Invalid exception object ID:<" + exception.objectID + ">",
+ exception.objectID, 0);
+ assertEquals("Invalid exception tag,", JDWPConstants.Tag.OBJECT_TAG, exception.tag
+ , JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG)
+ , JDWPConstants.Tag.getName(exception.tag));
+ logWriter.println(" InterfaceType.InvokeMethod: exception.tag="
+ + exception.tag + " exception.objectID=" + exception.objectID);
+ }
+
+ assertAllDataRead(reply);
+
+ // Let's resume application suspended on the METHOD_ENTRY event.
+ debuggeeWrapper.vmMirror.resume();
+
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
+ }
+
+ public void testInvokeMethodStaticWithoutThrowing() {
+ testInvokeMethodStatic(false);
+ }
+ public void testInvokeMethodStaticThrowing() {
+ testInvokeMethodStatic(true);
+ }
+}
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/InterfaceType/InvokeMethodTestInterface.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/InterfaceType/InvokeMethodTestInterface.java
new file mode 100644
index 0000000..d36f0d9
--- /dev/null
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/InterfaceType/InvokeMethodTestInterface.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.jpda.tests.jdwp.InterfaceType;
+
+import org.apache.harmony.jpda.tests.framework.LogWriter;
+import org.apache.harmony.jpda.tests.share.JPDATestOptions;
+
+/**
+ * Used for InterfaceType.InvokeMethodTest
+ */
+public interface InvokeMethodTestInterface {
+ public static final int RETURN_VALUE = 567;
+ public static int testInvokeMethodStatic1(boolean needsThrow) throws Throwable {
+ if (needsThrow) {
+ throw new Throwable("test exception");
+ }
+ return InvokeMethodTestInterface.RETURN_VALUE;
+ }
+}
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault002Debuggee.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault002Debuggee.java
new file mode 100644
index 0000000..efb3dbc
--- /dev/null
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault002Debuggee.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.jpda.tests.jdwp.ObjectReference;
+
+import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
+import org.apache.harmony.jpda.tests.share.SyncDebuggee;
+
+public class InvokeMethodDefault002Debuggee extends SyncDebuggee {
+
+ /**
+ * Interface defining the default method to be invoked.
+ */
+ static interface TestInterface {
+ public static final int RETURN_VALUE = 123;
+ /**
+ * Method invoked for test
+ * @param shouldThrow throws if the value is true.
+ * @return the value 123
+ */
+ public default int testDefaultMethod(boolean shouldThrow) throws Throwable {
+ if (shouldThrow) {
+ throw new Throwable("testDefaultMethod");
+ }
+ return TestInterface.RETURN_VALUE;
+ }
+ }
+
+ /**
+ * The overriding class we will initialize to call the default method.
+ */
+ static class TestClass implements TestInterface {
+ public static final int RETURN_VALUE = 456;
+ @Override
+ public int testDefaultMethod(boolean shouldThrow) throws Throwable {
+ if (shouldThrow) {
+ throw new Throwable("testDefaultMethod");
+ }
+ return TestClass.RETURN_VALUE;
+ }
+ }
+
+ // The instance used to invoke "TestClass.testMethod".
+ static TestClass invokeReceiver = new TestClass();
+
+ void execMethod() {
+ logWriter.println("InvokeMethodDefault002Debuggee.execMethod()");
+ }
+
+ public void run() {
+ // Preload TestClass so it is available during the test.
+ Class c = null;
+ String packageName = "org.apache.harmony.jpda.tests.jdwp.";
+ try {
+ c = Class.forName(
+ packageName + "ObjectReference.InvokeMethodDefault002Debuggee$TestClass");
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY);
+ logWriter.println("InvokeMethodDefault002Debuggee");
+ synchronizer.receiveMessageWithoutException(
+ packageName + "ObjectReference.InvokeMethodDefault002Debuggee(#1)");
+ execMethod();
+ synchronizer.receiveMessageWithoutException(
+ packageName + "ObjectReference.InvokeMethodDefault002Debuggee(#2)");
+ }
+
+ public static void main(String[] args) {
+ runDebuggee(InvokeMethodDefault002Debuggee.class);
+ }
+}
+
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault002Test.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault002Test.java
new file mode 100644
index 0000000..7aaf026
--- /dev/null
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault002Test.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.jpda.tests.jdwp.ObjectReference;
+
+import org.apache.harmony.jpda.tests.framework.jdwp.*;
+import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
+import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
+
+
+/**
+ * JDWP unit test for ObjectReference.InvokeMethod command on an
+ * overridden default method.
+ */
+public class InvokeMethodDefault002Test extends JDWPSyncTestCase {
+ protected String getDebuggeeClassName() {
+ return InvokeMethodDefault002Debuggee.class.getName();
+ }
+
+ /**
+ * This testcase exercises ObjectReference.InvokeMethod command.
+ * <BR>The test first starts the debuggee, requests METHOD_ENTRY event so
+ * the application suspends on first invoke.
+ * <BR>Then sends ObjectReference.InvokeMethod command to invoke method
+ * InvokeMethodDefaultTest$TestInterface.testDefaultMethod on an instance
+ * of a subclass of Object overriding the method toString.
+ * <BR>Checks that returned value is expected string value and returned
+ * exception object is null.
+ * <BR>Finally resumes the application.
+ * @param shouldThrow If true test that we can make the function throw.
+ */
+ private void testInvokeMethod(boolean shouldThrow) {
+ synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
+
+ // Get debuggee class ID.
+ String debuggeeClassSig = getDebuggeeClassSignature();
+ long debuggeeTypeID = debuggeeWrapper.vmMirror.getClassID(debuggeeClassSig);
+ assertTrue("Failed to find debuggee class", debuggeeTypeID != 0L);
+
+ // Set METHOD_ENTRY event request so application is suspended.
+ CommandPacket packet = new CommandPacket(
+ JDWPCommands.EventRequestCommandSet.CommandSetID,
+ JDWPCommands.EventRequestCommandSet.SetCommand);
+ packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
+ packet.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL);
+ packet.setNextValueAsInt(1); // number of modifiers
+ packet.setNextValueAsByte(EventMod.ModKind.ClassOnly); // class-only modifier.
+ packet.setNextValueAsReferenceTypeID(debuggeeTypeID);
+ ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
+ checkReplyPacket(reply, "EventRequest::Set command");
+
+ int requestID = reply.getNextValueAsInt();
+ logWriter.println(" EventRequest.Set: requestID=" + requestID);
+ assertAllDataRead(reply);
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
+
+ long targetThreadID = 0;
+ // Wait for METHOD_ENTRY event and collect event thread.
+ CommandPacket event = debuggeeWrapper.vmMirror.receiveEvent();
+ byte suspendPolicy = event.getNextValueAsByte();
+ int events = event.getNextValueAsInt();
+ logWriter.println(
+ " EVENT_THREAD event: suspendPolicy=" + suspendPolicy + " events=" + events);
+ for (int i = 0; i < events; i++) {
+ byte eventKind = event.getNextValueAsByte();
+ int newRequestID = event.getNextValueAsInt();
+ long threadID = event.getNextValueAsThreadID();
+ event.getNextValueAsLocation(); // location
+ logWriter.println(" EVENT_THREAD event " + i + ": eventKind="
+ + eventKind + " requestID=" + newRequestID + " threadID="
+ + threadID);
+ if (newRequestID == requestID) {
+ targetThreadID = threadID;
+ }
+ }
+ assertAllDataRead(event);
+ assertTrue("Invalid targetThreadID, must be != 0", targetThreadID != 0L);
+
+ // Now we're suspended, clear event request.
+ debuggeeWrapper.vmMirror.clearEvent(JDWPConstants.EventKind.METHOD_ENTRY, requestID);
+
+ // Load value of the invoke's receiver.
+ long receiverFieldID =
+ debuggeeWrapper.vmMirror.getFieldID(debuggeeTypeID, "invokeReceiver");
+ assertTrue("Failed to find receiver field", receiverFieldID != 0L);
+
+ logWriter.println(" Send ReferenceType.GetValues");
+ Value fieldValue = debuggeeWrapper.vmMirror.getReferenceTypeValue(debuggeeTypeID, receiverFieldID);
+ assertNotNull("Received null value", fieldValue);
+ assertEquals("Expected an object value", JDWPConstants.Tag.OBJECT_TAG, fieldValue.getTag());
+ long receiverObjectID = fieldValue.getLongValue();
+ assertTrue("Field is null", receiverObjectID != 0L);
+
+ // Get test class ID.
+ String testClassSig = getClassSignature(InvokeMethodDefault002Debuggee.TestClass.class);
+ long testTypeID = debuggeeWrapper.vmMirror.getClassID(testClassSig);
+ assertTrue("Failed to find test class", testTypeID != 0L);
+
+ // Get InvokeMethodDefaultDebuggee.TestInterface class ID.
+ long interfaceTypeID = debuggeeWrapper.vmMirror.getInterfaceID(
+ getClassSignature(InvokeMethodDefault002Debuggee.TestInterface.class));
+ assertTrue("Failed to find InvokeMethodDefault002Debuggee.TestInterface class",
+ interfaceTypeID != 0L);
+
+ // Get InvokeMethodDefaultDebuggee.TestInterface.testDefaultMethod method ID.
+ long targetMethodID =
+ debuggeeWrapper.vmMirror.getMethodID(interfaceTypeID, "testDefaultMethod");
+ assertTrue("Failed to find method", targetMethodID != 0L);
+ logWriter.println(" Method ID=" + targetMethodID);
+
+ // The method argument.
+ Value throwValue = new Value(shouldThrow);
+ // Invoke method.
+ packet = new CommandPacket(
+ JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
+ JDWPCommands.ObjectReferenceCommandSet.InvokeMethodCommand);
+ packet.setNextValueAsObjectID(receiverObjectID);
+ packet.setNextValueAsThreadID(targetThreadID);
+ packet.setNextValueAsClassID(testTypeID); // TestClass type ID.
+ packet.setNextValueAsMethodID(targetMethodID); // testDefaultMethod method ID.
+ packet.setNextValueAsInt(1); // 1 argument.
+ packet.setNextValueAsValue(throwValue);
+ packet.setNextValueAsInt(0); // invoke options.
+ logWriter.println(" Send ObjectReference.InvokeMethod " +
+ ((shouldThrow) ? "with" : "without") + " exception");
+ reply = debuggeeWrapper.vmMirror.performCommand(packet);
+ checkReplyPacket(reply, "ObjectReference::InvokeMethod command");
+
+ Value returnValue = reply.getNextValueAsValue();
+ assertNotNull("Returned value is null", returnValue);
+ if (shouldThrow) {
+ assertEquals("Invalid returned value,", 0, returnValue.getIntValue());
+ logWriter.println(" ObjectReference.InvokeMethod: returnValue.getIntValue()="
+ + returnValue.getIntValue());
+
+ // Check that some exception was thrown.
+ TaggedObject exception = reply.getNextValueAsTaggedObject();
+ assertNotNull("Returned exception is null", exception);
+ assertTrue("Invalid exception object ID:<" + exception.objectID + ">",
+ exception.objectID != 0L);
+ assertEquals("Invalid exception tag,", JDWPConstants.Tag.OBJECT_TAG, exception.tag
+ , JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG)
+ , JDWPConstants.Tag.getName(exception.tag));
+ logWriter.println(" InterfaceType.InvokeMethod: exception.tag="
+ + exception.tag + " exception.objectID=" + exception.objectID);
+ } else {
+ assertEquals("Invalid returned value,",
+ InvokeMethodDefault002Debuggee.TestClass.RETURN_VALUE, returnValue.getIntValue());
+ logWriter.println(" ObjectReference.InvokeMethod: returnValue.getIntValue()="
+ + returnValue.getIntValue());
+
+ TaggedObject exception = reply.getNextValueAsTaggedObject();
+ assertNotNull("Returned exception is null", exception);
+ assertEquals("Invalid exception object ID:<" + exception.objectID + ">",
+ exception.objectID, 0);
+ assertEquals("Invalid exception tag,", JDWPConstants.Tag.OBJECT_TAG, exception.tag
+ , JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG)
+ , JDWPConstants.Tag.getName(exception.tag));
+ logWriter.println(" ObjectReference.InvokeMethod: exception.tag="
+ + exception.tag + " exception.objectID=" + exception.objectID);
+ }
+
+ // Let's resume application
+ debuggeeWrapper.vmMirror.resume();
+
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
+ }
+
+ public void testInvokeMethodFromInterfaceThrow() {
+ testInvokeMethod(true);
+ }
+
+ public void testInvokeMethodFromInterfaceNoThrow() {
+ testInvokeMethod(false);
+ }
+}
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefaultDebuggee.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefaultDebuggee.java
new file mode 100644
index 0000000..b3b5e97
--- /dev/null
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefaultDebuggee.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.jpda.tests.jdwp.ObjectReference;
+
+import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
+import org.apache.harmony.jpda.tests.share.SyncDebuggee;
+
+public class InvokeMethodDefaultDebuggee extends SyncDebuggee {
+
+ /**
+ * Interface defining the default method to be invoked.
+ */
+ public static interface TestInterface {
+ public static final int RETURN_VALUE = 123;
+ /**
+ * Method invoked for test
+ * @param shouldThrow throws if the value is true.
+ * @return the value 123
+ */
+ public default int testDefaultMethod(boolean shouldThrow) throws Throwable {
+ if (shouldThrow) {
+ throw new Throwable("testDefaultMethod");
+ }
+ return TestInterface.RETURN_VALUE;
+ }
+ }
+
+ /**
+ * The empty class we will initialize to call the default method.
+ */
+ public static class TestClass implements TestInterface {
+ }
+
+ // The instance used to invoke "TestClass.testMethod".
+ static TestClass invokeReceiver = new TestClass();
+
+ void execMethod() {
+ logWriter.println("InvokeMethodDefaultDebuggee.execMethod()");
+ }
+
+ public void run() {
+ // Preload TestClass so it is available during the test.
+ Class c = null;
+ String packageName = "org.apache.harmony.jpda.tests.jdwp.";
+ try {
+ c = Class.forName(
+ packageName + "ObjectReference.InvokeMethodDefaultDebuggee$TestClass");
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY);
+ logWriter.println("InvokeMethodDefaultDebuggee");
+ synchronizer.receiveMessageWithoutException(
+ packageName + "ObjectReference.InvokeMethodDefaultDebuggee(#1)");
+ execMethod();
+ synchronizer.receiveMessageWithoutException(
+ packageName + "ObjectReference.InvokeMethodDefaultDebuggee(#2)");
+ }
+
+ public static void main(String[] args) {
+ runDebuggee(InvokeMethodDefaultDebuggee.class);
+ }
+}
+
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefaultTest.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefaultTest.java
new file mode 100644
index 0000000..0f2a386
--- /dev/null
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefaultTest.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.jpda.tests.jdwp.ObjectReference;
+
+import org.apache.harmony.jpda.tests.framework.jdwp.*;
+import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase;
+import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
+
+
+/**
+ * JDWP unit test for ObjectReference.InvokeMethod command.
+ */
+public class InvokeMethodDefaultTest extends JDWPSyncTestCase {
+ protected String getDebuggeeClassName() {
+ return InvokeMethodDefaultDebuggee.class.getName();
+ }
+
+ /**
+ * This testcase exercises ObjectReference.InvokeMethod command.
+ * <BR>The test first starts the debuggee, requests METHOD_ENTRY event so
+ * the application suspends on first invoke.
+ * <BR>Then sends ObjectReference.InvokeMethod command to invoke method
+ * InvokeMethodDefaultTest$TestInterface.testDefaultMethod on an instance
+ * of a subclass of Object overriding the method toString.
+ * <BR>Checks that returned value is expected string value and returned
+ * exception object is null.
+ * <BR>Finally resumes the application.
+ * @param shouldThrow If true test that we can make the function throw.
+ */
+ private void testInvokeMethod(boolean shouldThrow) {
+ synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY);
+
+ // Get debuggee class ID.
+ String debuggeeClassSig = getDebuggeeClassSignature();
+ long debuggeeTypeID = debuggeeWrapper.vmMirror.getClassID(debuggeeClassSig);
+ assertTrue("Failed to find debuggee class", debuggeeTypeID != 0L);
+
+ // Set METHOD_ENTRY event request so application is suspended.
+ CommandPacket packet = new CommandPacket(
+ JDWPCommands.EventRequestCommandSet.CommandSetID,
+ JDWPCommands.EventRequestCommandSet.SetCommand);
+ packet.setNextValueAsByte(JDWPConstants.EventKind.METHOD_ENTRY);
+ packet.setNextValueAsByte(JDWPConstants.SuspendPolicy.ALL);
+ packet.setNextValueAsInt(1);
+ packet.setNextValueAsByte(EventMod.ModKind.ClassOnly); // class-only modifier.
+ packet.setNextValueAsReferenceTypeID(debuggeeTypeID);
+ ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
+ checkReplyPacket(reply, "EventRequest::Set command");
+
+ int requestID = reply.getNextValueAsInt();
+ logWriter.println(" EventRequest.Set: requestID=" + requestID);
+ assertAllDataRead(reply);
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
+
+ long targetThreadID = 0;
+ // Wait for METHOD_ENTRY event and collect event thread.
+ CommandPacket event = debuggeeWrapper.vmMirror.receiveEvent();
+ byte suspendPolicy = event.getNextValueAsByte();
+ int events = event.getNextValueAsInt();
+ logWriter.println(" EVENT_THREAD event: suspendPolicy=" + suspendPolicy +
+ " events=" + events);
+ for (int i = 0; i < events; i++) {
+ byte eventKind = event.getNextValueAsByte();
+ int newRequestID = event.getNextValueAsInt();
+ long threadID = event.getNextValueAsThreadID();
+ //Location location =
+ event.getNextValueAsLocation();
+ logWriter.println(" EVENT_THREAD event " + i + ": eventKind="
+ + eventKind + " requestID=" + newRequestID + " threadID="
+ + threadID);
+ if (newRequestID == requestID) {
+ targetThreadID = threadID;
+ }
+ }
+ assertAllDataRead(event);
+ assertTrue("Invalid targetThreadID, must be != 0", targetThreadID != 0L);
+
+ // Now we're suspended, clear event request.
+ debuggeeWrapper.vmMirror.clearEvent(JDWPConstants.EventKind.METHOD_ENTRY, requestID);
+
+ // Load value of the invoke's receiver.
+ long receiverFieldID =
+ debuggeeWrapper.vmMirror.getFieldID(debuggeeTypeID, "invokeReceiver");
+ assertTrue("Failed to find receiver field", receiverFieldID != 0L);
+
+ logWriter.println(" Send ReferenceType.GetValues");
+ Value fieldValue = debuggeeWrapper.vmMirror.getReferenceTypeValue(debuggeeTypeID, receiverFieldID);
+ assertNotNull("Received null value", fieldValue);
+ assertEquals("Expected an object value", JDWPConstants.Tag.OBJECT_TAG, fieldValue.getTag());
+ long receiverObjectID = fieldValue.getLongValue();
+ assertTrue("Field is null", receiverObjectID != 0L);
+
+ // Get test class ID.
+ String testClassSig = getClassSignature(InvokeMethodDefaultDebuggee.TestClass.class);
+ long testTypeID = debuggeeWrapper.vmMirror.getClassID(testClassSig);
+ assertTrue("Failed to find test class", testTypeID != 0L);
+
+ // Get InvokeMethodDefualtDebuggee.TestInterface class ID.
+ long interfaceTypeID = debuggeeWrapper.vmMirror.getInterfaceID(
+ getClassSignature(InvokeMethodDefaultDebuggee.TestInterface.class));
+ assertTrue("Failed to find InvokeMethodDefaultDebuggee.TestInterface class",
+ interfaceTypeID != 0L);
+
+ // Get InvokeMethodDefualtDebuggee.TestInterface.testDefaultMethod method ID.
+ long targetMethodID =
+ debuggeeWrapper.vmMirror.getMethodID(interfaceTypeID, "testDefaultMethod");
+ assertTrue("Failed to find method", targetMethodID != 0L);
+ logWriter.println(" Method ID=" + targetMethodID);
+
+ // The method argument.
+ Value throwValue = new Value(shouldThrow);
+ // Invoke method.
+ packet = new CommandPacket(
+ JDWPCommands.ObjectReferenceCommandSet.CommandSetID,
+ JDWPCommands.ObjectReferenceCommandSet.InvokeMethodCommand);
+ packet.setNextValueAsObjectID(receiverObjectID);
+ packet.setNextValueAsThreadID(targetThreadID);
+ packet.setNextValueAsClassID(testTypeID); // TestClass type ID.
+ packet.setNextValueAsMethodID(targetMethodID); // testDefaultMethod method ID.
+ packet.setNextValueAsInt(1); // 1 argument.
+ packet.setNextValueAsValue(throwValue);
+ packet.setNextValueAsInt(0); // invoke options.
+ logWriter.println(" Send ObjectReference.InvokeMethod " +
+ ((shouldThrow) ? "with" : "without") + " exception");
+ reply = debuggeeWrapper.vmMirror.performCommand(packet);
+ checkReplyPacket(reply, "ObjectReference::InvokeMethod command");
+
+ Value returnValue = reply.getNextValueAsValue();
+ assertNotNull("Returned value is null", returnValue);
+ if (shouldThrow) {
+ assertEquals("Invalid returned value,", 0, returnValue.getIntValue());
+ logWriter.println(" ObjectReference.InvokeMethod: returnValue.getIntValue()="
+ + returnValue.getIntValue());
+
+ // Check that some exception was thrown.
+ TaggedObject exception = reply.getNextValueAsTaggedObject();
+ assertNotNull("Returned exception is null", exception);
+ assertTrue("Invalid exception object ID:<" + exception.objectID + ">",
+ exception.objectID != 0L);
+ assertEquals("Invalid exception tag,", JDWPConstants.Tag.OBJECT_TAG, exception.tag
+ , JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG)
+ , JDWPConstants.Tag.getName(exception.tag));
+ logWriter.println(" InterfaceType.InvokeMethod: exception.tag="
+ + exception.tag + " exception.objectID=" + exception.objectID);
+ } else {
+ assertEquals("Invalid returned value,",
+ InvokeMethodDefaultDebuggee.TestInterface.RETURN_VALUE, returnValue.getIntValue());
+ logWriter.println(" ObjectReference.InvokeMethod: returnValue.getIntValue()="
+ + returnValue.getIntValue());
+
+ TaggedObject exception = reply.getNextValueAsTaggedObject();
+ assertNotNull("Returned exception is null", exception);
+ assertEquals("Invalid exception object ID:<" + exception.objectID + ">",
+ exception.objectID, 0);
+ assertEquals("Invalid exception tag,", JDWPConstants.Tag.OBJECT_TAG, exception.tag
+ , JDWPConstants.Tag.getName(JDWPConstants.Tag.OBJECT_TAG)
+ , JDWPConstants.Tag.getName(exception.tag));
+ logWriter.println(" ObjectReference.InvokeMethod: exception.tag="
+ + exception.tag + " exception.objectID=" + exception.objectID);
+ }
+
+ // Let's resume application
+ debuggeeWrapper.vmMirror.resume();
+
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
+ }
+
+ public void testInvokeMethodFromInterfaceThrow() {
+ testInvokeMethod(true);
+ }
+
+ public void testInvokeMethodFromInterfaceNoThrow() {
+ testInvokeMethod(false);
+ }
+}
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java
index 412a87b..5618247 100644
--- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java
+++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java
@@ -114,6 +114,7 @@
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.ThreadStartTest.class);
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.VMDeath002Test.class);
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Events.VMDeathTest.class);
+ suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.InterfaceType.InvokeMethodTest.class);
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Method.BytecodesTest.class);
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Method.IsObsoleteTest.class);
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Method.LineTableTest.class);
@@ -142,6 +143,8 @@
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ObjectReference.InvokeMethod003Test.class);
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ObjectReference.InvokeMethodTest.class);
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ObjectReference.InvokeMethodAfterMultipleThreadSuspensionTest.class);
+ suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ObjectReference.InvokeMethodDefault002Test.class);
+ suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ObjectReference.InvokeMethodDefaultTest.class);
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ObjectReference.InvokeMethodWithSuspensionTest.class);
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ObjectReference.IsCollectedTest.class);
suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ObjectReference.MonitorInfoTest.class);