test/jdk/com/sun/jdi/InterfaceMethodsTest.java
changeset 47216 71c04702a3d5
parent 44423 306c020eb154
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /**
       
    25  * @test
       
    26  * @bug 8031195
       
    27  * @bug 8071657
       
    28  * @bug 8165827
       
    29  * @summary  JDI: Add support for static, private and default methods in interfaces
       
    30  *
       
    31  * @run build TestScaffold VMConnection TargetListener TargetAdapter
       
    32  * @run build InterfaceMethodsTest
       
    33  * @run driver InterfaceMethodsTest
       
    34  */
       
    35 import com.sun.jdi.*;
       
    36 import com.sun.jdi.event.*;
       
    37 import java.util.Collections;
       
    38 import java.util.Iterator;
       
    39 import java.util.List;
       
    40 
       
    41 public class InterfaceMethodsTest extends TestScaffold {
       
    42     private static final int RESULT_A = 1;
       
    43     private static final int RESULT_B = 2;
       
    44     private static final int RESULT_TARGET = 3;
       
    45 
       
    46     static interface InterfaceA {
       
    47         static int staticMethodA() {
       
    48             System.out.println("-InterfaceA: static interface method A-");
       
    49             return RESULT_A;
       
    50         }
       
    51         static int staticMethodB() {
       
    52             System.out.println("-InterfaceA: static interface method B-");
       
    53             return RESULT_A;
       
    54         }
       
    55         default int defaultMethodA() {
       
    56             System.out.println("-InterfaceA: default interface method A-");
       
    57             return RESULT_A;
       
    58         }
       
    59         default int defaultMethodB() {
       
    60             System.out.println("-InterfaceA: default interface method B-");
       
    61             return RESULT_A;
       
    62         }
       
    63         default int defaultMethodC() {
       
    64             System.out.println("-InterfaceA: default interface method C-");
       
    65             return RESULT_A;
       
    66         }
       
    67         private int privateMethodA() {
       
    68             System.out.println("-InterfaceA: private interface method A-");
       
    69             return RESULT_A;
       
    70         }
       
    71         int implementedMethod();
       
    72     }
       
    73 
       
    74     static interface InterfaceB extends InterfaceA {
       
    75         @Override
       
    76         default int defaultMethodC() {
       
    77             System.out.println("-InterfaceB: overridden default interface method C-");
       
    78             return RESULT_B;
       
    79         }
       
    80         default int defaultMethodD() {
       
    81             System.out.println("-InterfaceB: default interface method D-");
       
    82             return RESULT_B;
       
    83         }
       
    84         static int staticMethodB() {
       
    85             System.out.println("-InterfaceB: overridden static interface method B-");
       
    86             return RESULT_B;
       
    87         }
       
    88         static int staticMethodC() {
       
    89             System.out.println("-InterfaceB: static interface method C-");
       
    90             return RESULT_B;
       
    91         }
       
    92         private int privateMethodB() {
       
    93             System.out.println("-InterfaceB: private interface method B-");
       
    94             return RESULT_B;
       
    95         }
       
    96     }
       
    97 
       
    98     final static class TargetClass implements InterfaceB {
       
    99         public int classMethod() {
       
   100             System.out.println("-TargetClass: class only method-");
       
   101             return RESULT_TARGET;
       
   102         }
       
   103 
       
   104         @Override
       
   105         public int implementedMethod() {
       
   106             System.out.println("-TargetClass: implemented non-default interface method-");
       
   107             return RESULT_TARGET;
       
   108         }
       
   109 
       
   110         @Override
       
   111         public int defaultMethodB() {
       
   112             System.out.println("-TargetClass: overridden default interface method B");
       
   113 
       
   114             return RESULT_TARGET;
       
   115         }
       
   116 
       
   117         public static void main(String[] args) {
       
   118             TargetClass tc = new TargetClass();
       
   119             tc.doTests(tc);
       
   120         }
       
   121 
       
   122         private void doTests(TargetClass ref) {
       
   123             // break
       
   124         }
       
   125     }
       
   126 
       
   127     public InterfaceMethodsTest(String[] args) {
       
   128         super(args);
       
   129     }
       
   130 
       
   131     public static void main(String[] args) throws Exception {
       
   132         new InterfaceMethodsTest(args).startTests();
       
   133     }
       
   134 
       
   135     private static final String TEST_CLASS_NAME = InterfaceMethodsTest.class.getName().replace('.', '/');
       
   136     private static final String TARGET_CLASS_NAME = TargetClass.class.getName().replace('.', '/');
       
   137     private static final String INTERFACEA_NAME = InterfaceA.class.getName().replace('.', '/');
       
   138     private static final String INTERFACEB_NAME = InterfaceB.class.getName().replace('.', '/');
       
   139 
       
   140     protected void runTests() throws Exception {
       
   141         /*
       
   142          * Get to the top of main()
       
   143          * to determine targetClass and mainThread
       
   144          */
       
   145         BreakpointEvent bpe = startToMain(TARGET_CLASS_NAME);
       
   146 
       
   147         bpe = resumeTo(TARGET_CLASS_NAME, "doTests", "(L" + TARGET_CLASS_NAME +";)V");
       
   148 
       
   149         mainThread = bpe.thread();
       
   150 
       
   151         StackFrame frame = mainThread.frame(0);
       
   152         ObjectReference thisObject = frame.thisObject();
       
   153         ObjectReference ref = (ObjectReference)frame.getArgumentValues().get(0);
       
   154 
       
   155         ReferenceType targetClass = bpe.location().declaringType();
       
   156         testImplementationClass(targetClass, thisObject);
       
   157 
       
   158         testInterfaceA(ref);
       
   159 
       
   160         testInterfaceB(ref);
       
   161 
       
   162         /*
       
   163          * resume the target listening for events
       
   164          */
       
   165         listenUntilVMDisconnect();
       
   166 
       
   167         /*
       
   168          * deal with results of test
       
   169          * if anything has called failure("foo") testFailed will be true
       
   170          */
       
   171         if (!testFailed) {
       
   172             println("InterfaceMethodsTest: passed");
       
   173         } else {
       
   174             throw new Exception("InterfaceMethodsTest: failed");
       
   175         }
       
   176     }
       
   177 
       
   178     private void testInterfaceA(ObjectReference ref) {
       
   179 
       
   180         ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEA_NAME).get(0);
       
   181 
       
   182         /* Private method calls */
       
   183 
       
   184         Method m = testLookup(ifaceClass, "privateMethodA", "()I", true, null); // should succeed
       
   185 
       
   186         testInvokePos(m, ref, vm().mirrorOf(RESULT_A), false);
       
   187         testInvokePos(m, ref, vm().mirrorOf(RESULT_A), true);
       
   188 
       
   189         // Test non-virtual calls on InterfaceA
       
   190 
       
   191         /* Default method calls */
       
   192 
       
   193         // invoke the InterfaceA's "defaultMethodA"
       
   194         testInvokePos(ifaceClass, ref, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A));
       
   195 
       
   196         // invoke the InterfaceA's "defaultMethodB"
       
   197         testInvokePos(ifaceClass, ref, "defaultMethodB", "()I", vm().mirrorOf(RESULT_A));
       
   198 
       
   199         // invoke the InterfaceA's "defaultMethodC"
       
   200         testInvokePos(ifaceClass, ref, "defaultMethodC", "()I", vm().mirrorOf(RESULT_A));
       
   201 
       
   202         // "defaultMethodD" from InterfaceB is not accessible from here
       
   203         testInvokeNeg(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B),
       
   204                       "Attempted to invoke non-existing method");
       
   205 
       
   206         // non-virtual invoke of the abstract method "implementedMethod" fails
       
   207         testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(TARGET_CLASS_NAME),
       
   208                       "Invocation of abstract methods is not supported");
       
   209 
       
   210         /* Static method calls */
       
   211 
       
   212         // invoke static interface method A
       
   213         testInvokePos(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A));
       
   214 
       
   215         // invoking static method A on the instance fails because static method A is
       
   216         // not inherited by TargetClass.
       
   217         testInvokeNeg(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
       
   218                       "Invalid MethodID");
       
   219 
       
   220         // invoke static interface method B
       
   221         testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
       
   222 
       
   223         // invoking static method B on the instance fails because static method B is
       
   224         // not inherited by TargetClass.
       
   225         testInvokeNeg(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A),
       
   226                       "Invalid MethodID");
       
   227 
       
   228         // try to invoke a virtual method
       
   229         testInvokePos(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET), true);
       
   230     }
       
   231 
       
   232     private void testInterfaceB(ObjectReference ref) {
       
   233         // Test non-virtual calls on InterfaceB
       
   234         ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEB_NAME).get(0);
       
   235 
       
   236         /* private method calls */
       
   237 
       
   238         /* These should fail but won't because of JDK-8167416
       
   239         testLookup(ifaceClass, "privateMethodA", "()I", true, NoSuchMethodError.class); // should fail
       
   240         testLookup(ifaceClass, "privateMethodA", "()I", false, NoSuchMethodError.class); // should fail
       
   241         */
       
   242         Method m = testLookup(ifaceClass, "privateMethodB", "()I", true, null); // should succeed
       
   243         testInvokePos(m, ref, vm().mirrorOf(RESULT_B), false);
       
   244         testInvokePos(m, ref, vm().mirrorOf(RESULT_B), true);
       
   245 
       
   246         /* Default method calls */
       
   247 
       
   248         // invoke the inherited "defaultMethodA"
       
   249         testInvokePos(ifaceClass, ref, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A));
       
   250 
       
   251         // invoke the inherited "defaultMethodB"
       
   252         testInvokePos(ifaceClass, ref, "defaultMethodB", "()I", vm().mirrorOf(RESULT_A));
       
   253 
       
   254         // invoke the inherited and overridden "defaultMethodC"
       
   255         testInvokePos(ifaceClass, ref, "defaultMethodC", "()I", vm().mirrorOf(RESULT_B));
       
   256 
       
   257         // invoke InterfaceB only "defaultMethodD"
       
   258         testInvokePos(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B));
       
   259 
       
   260         // "implementedMethod" is not present in InterfaceB
       
   261         testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET),
       
   262                 "Invocation of non-default methods is not supported");
       
   263 
       
   264 
       
   265         /* Static method calls*/
       
   266 
       
   267         // "staticMethodA" must not be inherited by InterfaceB
       
   268         testInvokeNeg(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
       
   269                 "Static interface methods are not inheritable");
       
   270 
       
   271         // "staticMethodA" is not inherited by InterfaceB even from an actual instance
       
   272         testInvokeNeg(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
       
   273                 "Static interface methods are not inheritable");
       
   274 
       
   275         // "staticMethodB" is re-defined in InterfaceB
       
   276         testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_B));
       
   277 
       
   278         // the instance fails to invoke the re-defined form of "staticMethodB" from
       
   279         // InterfaceB because staticMethodB is not inherited by TargetClass
       
   280         testInvokeNeg(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_B),
       
   281                 "Invalid MethodID");
       
   282 
       
   283         // "staticMethodC" is present only in InterfaceB
       
   284         testInvokePos(ifaceClass, null, "staticMethodC", "()I", vm().mirrorOf(RESULT_B));
       
   285 
       
   286         // "staticMethodC" is not reachable from the instance because staticMethodC
       
   287         // is not inherited by TargetClass.
       
   288         testInvokeNeg(ifaceClass, ref, "staticMethodC", "()I", vm().mirrorOf(RESULT_B),
       
   289                 "Invalid MethodID");
       
   290     }
       
   291 
       
   292     private void testImplementationClass(ReferenceType targetClass, ObjectReference thisObject) {
       
   293         // Test invocations on the implementation object
       
   294 
       
   295         // Note: private interface calls have already been tested
       
   296 
       
   297         /* Default method calls */
       
   298 
       
   299         // "defaultMethodA" is accessible and not overridden
       
   300         testInvokePos(targetClass, thisObject, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A));
       
   301 
       
   302         // "defaultMethodB" is accessible and overridden in TargetClass
       
   303         testInvokePos(targetClass, thisObject, "defaultMethodB", "()I", vm().mirrorOf(RESULT_TARGET));
       
   304 
       
   305         // "defaultMethodC" is accessible and overridden in InterfaceB
       
   306         testInvokePos(targetClass, thisObject, "defaultMethodC", "()I", vm().mirrorOf(RESULT_B));
       
   307 
       
   308         // "defaultMethodD" is accessible
       
   309         testInvokePos(targetClass, thisObject, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B));
       
   310 
       
   311 
       
   312         /* Non-default instance method calls */
       
   313 
       
   314         // "classMethod" declared in TargetClass is accessible
       
   315         testInvokePos(targetClass, thisObject, "classMethod", "()I", vm().mirrorOf(RESULT_TARGET));
       
   316 
       
   317         // the abstract "implementedMethod" has been implemented in TargetClass
       
   318         testInvokePos(targetClass, thisObject, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET));
       
   319 
       
   320 
       
   321         /* Static method calls */
       
   322 
       
   323         // All the static methods declared by the interfaces are not reachable from the instance of the implementor class
       
   324         testInvokeNeg(targetClass, thisObject, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
       
   325                 "Static interface methods are not inheritable");
       
   326 
       
   327         testInvokeNeg(targetClass, thisObject, "staticMethodB", "()I", vm().mirrorOf(RESULT_B),
       
   328                 "Static interface methods are not inheritable");
       
   329 
       
   330         testInvokeNeg(targetClass, thisObject, "staticMethodC", "()I", vm().mirrorOf(RESULT_B),
       
   331                 "Static interface methods are not inheritable");
       
   332 
       
   333         // All the static methods declared by the interfaces are not reachable through the implementor class
       
   334         testInvokeNeg(targetClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
       
   335                 "Static interface methods are not inheritable");
       
   336 
       
   337         testInvokeNeg(targetClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_B),
       
   338                 "Static interface methods are not inheritable");
       
   339 
       
   340         testInvokeNeg(targetClass, null, "staticMethodC", "()I", vm().mirrorOf(RESULT_B),
       
   341                 "Static interface methods are not inheritable");
       
   342     }
       
   343 
       
   344     // Non-virtual invocation
       
   345     private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
       
   346                                String methodSig, Value value) {
       
   347         testInvokePos(targetClass, ref, methodName, methodSig, value, false);
       
   348     }
       
   349 
       
   350     // Lookup the named method in the targetClass and invoke on the given object (for instance methods)
       
   351     // using virtual, or non-virtual, invocation mode as specified, for instance methods. Verify the
       
   352     // expected return value.
       
   353     // Should succeed.
       
   354     private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
       
   355                                String methodSig, Value value, boolean virtual) {
       
   356         logInvocation(ref, methodName, methodSig, targetClass);
       
   357         try {
       
   358             invoke(targetClass, ref, methodName, methodSig, value, virtual);
       
   359             System.err.println("--- PASSED");
       
   360         } catch (Exception e) {
       
   361             System.err.println("--- FAILED");
       
   362             failure("FAILED: Invocation failed with error message " + e.getLocalizedMessage());
       
   363         }
       
   364     }
       
   365 
       
   366     // Invoke the given Method on the given object (for instance methods)
       
   367     // using virtual, or non-virtual, invocation mode as specified, for instance methods. Verify the
       
   368     // expected return value.
       
   369     // Should succeed.
       
   370     private void testInvokePos(Method method, ObjectReference ref, Value value, boolean virtual) {
       
   371         logInvocation(ref, method.name(), method.signature(), method.declaringType());
       
   372         try {
       
   373             invoke(method.declaringType(), ref, method, value, virtual);
       
   374             System.err.println("--- PASSED");
       
   375         } catch (Exception e) {
       
   376             System.err.println("--- FAILED");
       
   377             failure("FAILED: Invocation failed with error message " + e.getLocalizedMessage());
       
   378         }
       
   379     }
       
   380 
       
   381     // Non-virtual invocation - with lookup in targetClass
       
   382     private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
       
   383                                String methodSig, Value value, String msg) {
       
   384         testInvokeNeg(targetClass, ref, methodName, methodSig, value, msg, false);
       
   385     }
       
   386 
       
   387     // Lookup the named method in the targetClass and invoke on the given object (for instance methods)
       
   388     // using virtual, or non-virtual, invocation mode as specified, for instance methods. Verify the
       
   389     // expected return value.
       
   390     // Should fail - with msg decribing why failure was expected
       
   391     private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
       
   392                                String methodSig, Value value, String msg, boolean virtual) {
       
   393         logInvocation(ref, methodName, methodSig, targetClass);
       
   394         try {
       
   395             invoke(targetClass, ref, methodName, methodSig, value, virtual);
       
   396             System.err.println("--- FAILED");
       
   397             failure("FAILED: " + msg);
       
   398         } catch (Exception e) {
       
   399             System.err.println("--- PASSED");
       
   400 
       
   401         }
       
   402     }
       
   403 
       
   404     private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName,
       
   405                         String methodSig, Value value, boolean virtual) throws Exception {
       
   406 
       
   407         Method method = getMethod(targetClass, methodName, methodSig);
       
   408         if (method == null) {
       
   409             throw new Exception("Can't find method: " + methodName  + " for class = " + targetClass);
       
   410         }
       
   411         invoke(targetClass, ref, method, value, virtual);
       
   412     }
       
   413 
       
   414     private void invoke(ReferenceType targetClass, ObjectReference ref, Method method,
       
   415                         Value value, boolean virtual) throws Exception {
       
   416 
       
   417         println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method);
       
   418         println(method.declaringType().toString());
       
   419 
       
   420         Value returnValue = null;
       
   421         if (ref != null) {
       
   422             if (virtual) {
       
   423                 returnValue = invokeVirtual(ref, method);
       
   424             } else {
       
   425                 returnValue = invokeNonVirtual(ref, method);
       
   426             }
       
   427         } else {
       
   428             returnValue = invokeStatic(targetClass, method);
       
   429         }
       
   430 
       
   431         println("        return val = " + returnValue);
       
   432         // It has to be the same value as what we passed in!
       
   433         if (returnValue.equals(value)) {
       
   434             println("         " + method.name() + " return value matches: "
       
   435                     + value);
       
   436         } else {
       
   437             if (value != null) {
       
   438                 throw new Exception(method.name() + " returned: " + returnValue +
       
   439                                     " expected: " + value );
       
   440             } else {
       
   441                 println("         " + method.name() + " return value : " + returnValue);
       
   442             }
       
   443 
       
   444         }
       
   445     }
       
   446 
       
   447     private Value invokeNonVirtual(ObjectReference ref, Method method) throws Exception {
       
   448         return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
       
   449     }
       
   450 
       
   451     private Value invokeVirtual(ObjectReference ref, Method method) throws Exception {
       
   452         return ref.invokeMethod(mainThread, method, Collections.emptyList(), 0);
       
   453     }
       
   454 
       
   455     private Value invokeStatic(ReferenceType refType, Method method) throws Exception {
       
   456         if (refType instanceof ClassType) {
       
   457             return ((ClassType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
       
   458         } else {
       
   459             return ((InterfaceType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
       
   460         }
       
   461     }
       
   462 
       
   463     private Method getMethod(ReferenceType rt, String name, String signature) {
       
   464         if (rt == null) return null;
       
   465         Method m = findMethod(rt, name, signature);
       
   466         if (m == null) {
       
   467             if (rt instanceof ClassType) {
       
   468                 for (Object ifc : ((ClassType)rt).interfaces()) {
       
   469                     m = getMethod((ReferenceType)ifc, name, signature);
       
   470                     if (m != null) {
       
   471                         break;
       
   472                     }
       
   473                 }
       
   474                 if (m == null) {
       
   475                     m = getMethod(((ClassType)rt).superclass(), name, signature);
       
   476                 } else {
       
   477                     if (m.isStatic()) {
       
   478                         // interface static methods are not inherited
       
   479                         m = null;
       
   480                     }
       
   481                 }
       
   482             } else if (rt instanceof InterfaceType) {
       
   483                 for(Object ifc : ((InterfaceType)rt).superinterfaces()) {
       
   484                     m = getMethod((ReferenceType)ifc, name, signature);
       
   485                     if (m != null) {
       
   486                         if (m.isStatic()) {
       
   487                             // interface static methods are not inherited
       
   488                             m = null;
       
   489                         }
       
   490                         break;
       
   491                     }
       
   492                 }
       
   493             }
       
   494         }
       
   495 
       
   496         return m;
       
   497     }
       
   498 
       
   499     private void logInvocation(ObjectReference ref, String methodName, String methodSig, ReferenceType targetClass) {
       
   500         if (ref != null) {
       
   501             System.err.println("Invoking: " + ref.referenceType().name() + "." +
       
   502                     methodName + methodSig + " with target of type " +
       
   503                     targetClass.name());
       
   504         } else {
       
   505             System.err.println("Invoking static : " + targetClass.name() + "." +
       
   506                     methodName + methodSig);
       
   507         }
       
   508     }
       
   509 
       
   510     private Method testLookup(ReferenceType targetClass, String methodName, String methodSig,
       
   511                               boolean declaredOnly, Class<?> expectedException) {
       
   512 
       
   513         System.err.println("Looking up " + targetClass.name() + "." + methodName + methodSig);
       
   514         try {
       
   515             Method m = declaredOnly ?
       
   516                 lookupDeclaredMethod(targetClass, methodName, methodSig) :
       
   517                 lookupMethod(targetClass, methodName, methodSig);
       
   518 
       
   519             if (expectedException == null) {
       
   520                 System.err.println("--- PASSED");
       
   521                 return m;
       
   522             }
       
   523             else {
       
   524                 System.err.println("--- FAILED");
       
   525                 failure("FAILED: lookup succeeded but expected exception "
       
   526                         + expectedException.getSimpleName());
       
   527                 return null;
       
   528             }
       
   529         }
       
   530         catch (Throwable t) {
       
   531             if (t.getClass() != expectedException) {
       
   532                 System.err.println("--- FAILED");
       
   533                 failure("FAILED: got exception " + t + " but expected exception "
       
   534                         + expectedException.getSimpleName());
       
   535                 return null;
       
   536             }
       
   537             else {
       
   538                 System.err.println("--- PASSED");
       
   539                 return null;
       
   540             }
       
   541         }
       
   542     }
       
   543 
       
   544     private Method lookupMethod(ReferenceType targetClass, String methodName, String methodSig) {
       
   545         List methods = targetClass.allMethods();
       
   546         Iterator iter = methods.iterator();
       
   547         while (iter.hasNext()) {
       
   548             Method method = (Method)iter.next();
       
   549             if (method.name().equals(methodName) &&
       
   550                 method.signature().equals(methodSig)) {
       
   551                 return method;
       
   552             }
       
   553         }
       
   554         throw new NoSuchMethodError();
       
   555     }
       
   556 
       
   557     private Method lookupDeclaredMethod(ReferenceType targetClass, String methodName, String methodSig) {
       
   558         Method m = findMethod(targetClass, methodName, methodSig);
       
   559         if (m == null)
       
   560             throw new NoSuchMethodError();
       
   561         return m;
       
   562     }
       
   563 }