Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/reflect/Method/InterfaceStatic/StaticInterfaceMethodInWayOfDefault.java
38829 views
1
/*
2
* Copyright (c) 2013, 2014, 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 8009411
27
* @summary Test that a static method on an interface doesn't hide a default
28
* method with the same name and signature in a separate compilation
29
* scenario.
30
* @library /lib/testlibrary
31
* @build jdk.testlibrary.IOUtils
32
* @run main StaticInterfaceMethodInWayOfDefault
33
*/
34
35
import java.io.IOException;
36
import java.io.InputStream;
37
import java.lang.reflect.InvocationTargetException;
38
import java.lang.reflect.Method;
39
import java.util.concurrent.Callable;
40
41
import jdk.testlibrary.IOUtils;
42
43
public class StaticInterfaceMethodInWayOfDefault {
44
public interface A_v1 {
45
}
46
47
public interface A_v2 {
48
default void m() {
49
System.err.println("A.m() called");
50
}
51
}
52
53
public interface B extends A_v1 {
54
static void m() {
55
System.err.println("B.m() called");
56
}
57
}
58
59
public interface C_v1 extends B {
60
default void m() {
61
System.err.println("C.m() called");
62
}
63
}
64
65
public interface C_v2 extends B {
66
}
67
68
public static class TestTask implements Callable<String> {
69
@Override
70
public String call() {
71
try {
72
Method m = C_v1.class.getMethod("m", (Class<?>[])null);
73
return m.getDeclaringClass().getSimpleName();
74
} catch (NoSuchMethodException e) {
75
System.err.println("Couldn't find method");
76
return "ERROR";
77
}
78
}
79
}
80
81
public static void main(String[] args) throws Exception {
82
int errors = 0;
83
Callable<String> v1Task = new TestTask();
84
85
ClassLoader v2Loader = new V2ClassLoader(
86
StaticInterfaceMethodInWayOfDefault.class.getClassLoader());
87
Callable<String> v2Task = (Callable<String>) Class.forName(
88
TestTask.class.getName(),
89
true,
90
v2Loader).newInstance();
91
92
System.err.println("Running using _v1 classes:");
93
String res = v1Task.call();
94
if(!res.equals("C_v1")) {
95
System.err.println("Got wrong method, expecting C_v1, got: " + res);
96
errors++;
97
}
98
99
System.err.println("Running using _v2 classes:");
100
res = v2Task.call();
101
if(!res.equals("A_v1")) {
102
System.err.println("Got wrong method, expecting A_v1, got: " + res);
103
errors++;
104
}
105
106
if (errors != 0)
107
throw new RuntimeException("Errors found, check log for details");
108
}
109
110
/**
111
* A ClassLoader implementation that loads alternative implementations of
112
* classes. If class name ends with "_v1" it locates instead a class with
113
* name ending with "_v2" and loads that class instead.
114
*/
115
static class V2ClassLoader extends ClassLoader {
116
V2ClassLoader(ClassLoader parent) {
117
super(parent);
118
}
119
120
@Override
121
protected Class<?> loadClass(String name, boolean resolve)
122
throws ClassNotFoundException {
123
if (name.indexOf('.') < 0) { // root package is our class
124
synchronized (getClassLoadingLock(name)) {
125
// First, check if the class has already been loaded
126
Class<?> c = findLoadedClass(name);
127
if (c == null) {
128
c = findClass(name);
129
}
130
if (resolve) {
131
resolveClass(c);
132
}
133
return c;
134
}
135
}
136
else { // not our class
137
return super.loadClass(name, resolve);
138
}
139
}
140
141
@Override
142
protected Class<?> findClass(String name)
143
throws ClassNotFoundException {
144
// special class name -> replace it with alternative name
145
if (name.endsWith("_v1")) {
146
String altName = name.substring(0, name.length() - 3) + "_v2";
147
String altPath = altName.replace('.', '/').concat(".class");
148
try (InputStream is = getResourceAsStream(altPath)) {
149
if (is != null) {
150
byte[] bytes = IOUtils.readFully(is);
151
// patch class bytes to contain original name
152
for (int i = 0; i < bytes.length - 2; i++) {
153
if (bytes[i] == '_' &&
154
bytes[i + 1] == 'v' &&
155
bytes[i + 2] == '2') {
156
bytes[i + 2] = '1';
157
}
158
}
159
return defineClass(name, bytes, 0, bytes.length);
160
}
161
else {
162
throw new ClassNotFoundException(name);
163
}
164
}
165
catch (IOException e) {
166
throw new ClassNotFoundException(name, e);
167
}
168
}
169
else { // not special class name -> just load the class
170
String path = name.replace('.', '/').concat(".class");
171
try (InputStream is = getResourceAsStream(path)) {
172
if (is != null) {
173
byte[] bytes = IOUtils.readFully(is);
174
return defineClass(name, bytes, 0, bytes.length);
175
}
176
else {
177
throw new ClassNotFoundException(name);
178
}
179
}
180
catch (IOException e) {
181
throw new ClassNotFoundException(name, e);
182
}
183
}
184
}
185
}
186
}
187
188