1 /*
   2  * Copyright (c) 2019, 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 package test;
  25 
  26 import java.lang.invoke.MethodHandle;
  27 import java.lang.invoke.MethodHandles;
  28 import java.lang.invoke.MethodHandles.Lookup;
  29 import java.lang.invoke.MethodType;
  30 import java.lang.reflect.Method;
  31 import java.util.Comparator;
  32 
  33 /*
  34  * java.util.Comparator is in java.base.  MyComparator is a Comparator
  35  * subclass and it's in a different module.
  36  *
  37  * Test findSpecial and unreflectSpecial with Comparator and MyComparator
  38  * as the special caller.
  39  */
  40 public class FindSpecial {
  41     private static final Lookup LOOKUP = MethodHandles.lookup();
  42 
  43     public static void main(String... args) throws Throwable {
  44         findSpecialTest();
  45         unreflectSpecialTest();
  46     }
  47 
  48     static void findSpecialTest() throws Throwable {
  49         Method m = Comparator.class.getMethod("reversed");
  50         MethodType mt = MethodType.methodType(m.getReturnType(), m.getParameterTypes());
  51         // refc and specialCaller are both in java.base
  52         MethodHandle mh = LOOKUP.findSpecial(Comparator.class, m.getName(), mt, Comparator.class);
  53         // refc in java.base, specialCaller in this module
  54         MethodHandle mh1 = LOOKUP.findSpecial(m.getDeclaringClass(), m.getName(), mt,
  55                                               MyComparator.class);
  56         Comparator<Object> cmp = new MyComparator();
  57         // invoke successfully
  58         Object o = mh.invoke(cmp);
  59         Object o1 = mh1.invoke(cmp);
  60     }
  61 
  62     static void unreflectSpecialTest() throws Throwable {
  63         Method m = Comparator.class.getMethod("reversed");
  64         // refc and specialCaller are both in java.base
  65         MethodHandle mh = LOOKUP.unreflectSpecial(m, Comparator.class);
  66         // refc in java.base, specialCaller in this module
  67         MethodHandle mh1 = LOOKUP.unreflectSpecial(m, MyComparator.class);
  68         Comparator<Object> cmp = new MyComparator();
  69         // invoke successfully
  70         Object o = mh.invoke(cmp);
  71         Object o1 = mh1.invoke(cmp);
  72     }
  73 
  74     static class MyComparator implements Comparator<Object> {
  75         public int compare(Object o1, Object o2) {
  76             return 0;
  77         }
  78 
  79         @Override
  80         public Comparator<Object> reversed() {
  81             throw new Error("should not reach here");
  82         }
  83     }
  84 } 
  85