Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java
38829 views
/*1* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 800941126* @summary Test that a static method on an interface doesn't hide a default27* method with the same name and signature in a separate compilation28* scenario.29* @library /lib/testlibrary30* @build jdk.testlibrary.IOUtils31* @run main StaticInterfaceMethodInWayOfDefault32*/3334import java.io.IOException;35import java.io.InputStream;36import java.lang.reflect.InvocationTargetException;37import java.lang.reflect.Method;38import java.util.concurrent.Callable;3940import jdk.testlibrary.IOUtils;4142public class StaticInterfaceMethodInWayOfDefault {43public interface A_v1 {44}4546public interface A_v2 {47default void m() {48System.err.println("A.m() called");49}50}5152public interface B extends A_v1 {53static void m() {54System.err.println("B.m() called");55}56}5758public interface C_v1 extends B {59default void m() {60System.err.println("C.m() called");61}62}6364public interface C_v2 extends B {65}6667public static class TestTask implements Callable<String> {68@Override69public String call() {70try {71Method m = C_v1.class.getMethod("m", (Class<?>[])null);72return m.getDeclaringClass().getSimpleName();73} catch (NoSuchMethodException e) {74System.err.println("Couldn't find method");75return "ERROR";76}77}78}7980public static void main(String[] args) throws Exception {81int errors = 0;82Callable<String> v1Task = new TestTask();8384ClassLoader v2Loader = new V2ClassLoader(85StaticInterfaceMethodInWayOfDefault.class.getClassLoader());86Callable<String> v2Task = (Callable<String>) Class.forName(87TestTask.class.getName(),88true,89v2Loader).newInstance();9091System.err.println("Running using _v1 classes:");92String res = v1Task.call();93if(!res.equals("C_v1")) {94System.err.println("Got wrong method, expecting C_v1, got: " + res);95errors++;96}9798System.err.println("Running using _v2 classes:");99res = v2Task.call();100if(!res.equals("A_v1")) {101System.err.println("Got wrong method, expecting A_v1, got: " + res);102errors++;103}104105if (errors != 0)106throw new RuntimeException("Errors found, check log for details");107}108109/**110* A ClassLoader implementation that loads alternative implementations of111* classes. If class name ends with "_v1" it locates instead a class with112* name ending with "_v2" and loads that class instead.113*/114static class V2ClassLoader extends ClassLoader {115V2ClassLoader(ClassLoader parent) {116super(parent);117}118119@Override120protected Class<?> loadClass(String name, boolean resolve)121throws ClassNotFoundException {122if (name.indexOf('.') < 0) { // root package is our class123synchronized (getClassLoadingLock(name)) {124// First, check if the class has already been loaded125Class<?> c = findLoadedClass(name);126if (c == null) {127c = findClass(name);128}129if (resolve) {130resolveClass(c);131}132return c;133}134}135else { // not our class136return super.loadClass(name, resolve);137}138}139140@Override141protected Class<?> findClass(String name)142throws ClassNotFoundException {143// special class name -> replace it with alternative name144if (name.endsWith("_v1")) {145String altName = name.substring(0, name.length() - 3) + "_v2";146String altPath = altName.replace('.', '/').concat(".class");147try (InputStream is = getResourceAsStream(altPath)) {148if (is != null) {149byte[] bytes = IOUtils.readFully(is);150// patch class bytes to contain original name151for (int i = 0; i < bytes.length - 2; i++) {152if (bytes[i] == '_' &&153bytes[i + 1] == 'v' &&154bytes[i + 2] == '2') {155bytes[i + 2] = '1';156}157}158return defineClass(name, bytes, 0, bytes.length);159}160else {161throw new ClassNotFoundException(name);162}163}164catch (IOException e) {165throw new ClassNotFoundException(name, e);166}167}168else { // not special class name -> just load the class169String path = name.replace('.', '/').concat(".class");170try (InputStream is = getResourceAsStream(path)) {171if (is != null) {172byte[] bytes = IOUtils.readFully(is);173return defineClass(name, bytes, 0, bytes.length);174}175else {176throw new ClassNotFoundException(name);177}178}179catch (IOException e) {180throw new ClassNotFoundException(name, e);181}182}183}184}185}186187188