Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/io/Serializable/failureAtomicity/FailureAtomicity.java
41153 views
1
/*
2
* Copyright (c) 2015, 2017, 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 8071474
27
* @summary Better failure atomicity for default read object.
28
* @modules jdk.compiler
29
* @library /test/lib
30
* @build jdk.test.lib.Platform
31
* jdk.test.lib.util.FileUtils
32
* @compile FailureAtomicity.java SerialRef.java
33
* @run main failureAtomicity.FailureAtomicity
34
*/
35
36
package failureAtomicity;
37
38
import java.io.ByteArrayInputStream;
39
import java.io.ByteArrayOutputStream;
40
import java.io.File;
41
import java.io.IOException;
42
import java.io.InputStream;
43
import java.io.ObjectInputStream;
44
import java.io.ObjectOutputStream;
45
import java.io.ObjectStreamClass;
46
import java.io.UncheckedIOException;
47
import java.lang.reflect.Constructor;
48
import java.net.URL;
49
import java.net.URLClassLoader;
50
import java.nio.file.Files;
51
import java.nio.file.Path;
52
import java.nio.file.Paths;
53
import java.util.ArrayList;
54
import java.util.Arrays;
55
import java.util.List;
56
import java.util.function.BiConsumer;
57
import java.util.stream.Collectors;
58
import javax.tools.JavaCompiler;
59
import javax.tools.JavaFileObject;
60
import javax.tools.StandardJavaFileManager;
61
import javax.tools.StandardLocation;
62
import javax.tools.ToolProvider;
63
import jdk.test.lib.util.FileUtils;
64
65
@SuppressWarnings("unchecked")
66
public class FailureAtomicity {
67
static final Path TEST_SRC = Paths.get(System.getProperty("test.src", "."));
68
static final Path TEST_CLASSES = Paths.get(System.getProperty("test.classes", "."));
69
static final Path fooTemplate = TEST_SRC.resolve("Foo.template");
70
static final Path barTemplate = TEST_SRC.resolve("Bar.template");
71
72
static final String[] PKGS = { "a.b.c", "x.y.z" };
73
74
public static void main(String[] args) throws Exception {
75
test_Foo();
76
test_BadFoo(); // 'Bad' => incompatible type; cannot be "fully" deserialized
77
test_FooWithReadObject();
78
test_BadFooWithReadObject();
79
80
test_Foo_Bar();
81
test_Foo_BadBar();
82
test_BadFoo_Bar();
83
test_BadFoo_BadBar();
84
test_Foo_BarWithReadObject();
85
test_Foo_BadBarWithReadObject();
86
test_BadFoo_BarWithReadObject();
87
test_BadFoo_BadBarWithReadObject();
88
test_FooWithReadObject_Bar();
89
test_FooWithReadObject_BadBar();
90
test_BadFooWithReadObject_Bar();
91
test_BadFooWithReadObject_BadBar();
92
}
93
94
static final BiConsumer<Object,Object> FOO_FIELDS_EQUAL = (a,b) -> {
95
try {
96
int aPrim = a.getClass().getField("fooPrim").getInt(a);
97
int bPrim = b.getClass().getField("fooPrim").getInt(b);
98
if (aPrim != bPrim)
99
throw new AssertionError("Not equal: (" + aPrim + "!=" + bPrim
100
+ "), in [" + a + "] [" + b + "]");
101
Object aRef = a.getClass().getField("fooRef").get(a);
102
Object bRef = b.getClass().getField("fooRef").get(b);
103
if (!aRef.equals(bRef))
104
throw new RuntimeException("Not equal: (" + aRef + "!=" + bRef
105
+ "), in [" + a + "] [" + b + "]");
106
} catch (NoSuchFieldException | IllegalAccessException x) {
107
throw new InternalError(x);
108
}
109
};
110
static final BiConsumer<Object,Object> FOO_FIELDS_DEFAULT = (ignore,b) -> {
111
try {
112
int aPrim = b.getClass().getField("fooPrim").getInt(b);
113
if (aPrim != 0)
114
throw new AssertionError("Expected 0, got:" + aPrim
115
+ ", in [" + b + "]");
116
Object aRef = b.getClass().getField("fooRef").get(b);
117
if (aRef != null)
118
throw new RuntimeException("Expected null, got:" + aRef
119
+ ", in [" + b + "]");
120
} catch (NoSuchFieldException | IllegalAccessException x) {
121
throw new InternalError(x);
122
}
123
};
124
static final BiConsumer<Object,Object> BAR_FIELDS_EQUAL = (a,b) -> {
125
try {
126
long aPrim = a.getClass().getField("barPrim").getLong(a);
127
long bPrim = b.getClass().getField("barPrim").getLong(b);
128
if (aPrim != bPrim)
129
throw new AssertionError("Not equal: (" + aPrim + "!=" + bPrim
130
+ "), in [" + a + "] [" + b + "]");
131
Object aRef = a.getClass().getField("barRef").get(a);
132
Object bRef = b.getClass().getField("barRef").get(b);
133
if (!aRef.equals(bRef))
134
throw new RuntimeException("Not equal: (" + aRef + "!=" + bRef
135
+ "), in [" + a + "] [" + b + "]");
136
} catch (NoSuchFieldException | IllegalAccessException x) {
137
throw new InternalError(x);
138
}
139
};
140
static final BiConsumer<Object,Object> BAR_FIELDS_DEFAULT = (ignore,b) -> {
141
try {
142
long aPrim = b.getClass().getField("barPrim").getLong(b);
143
if (aPrim != 0L)
144
throw new AssertionError("Expected 0, got:" + aPrim
145
+ ", in [" + b + "]");
146
Object aRef = b.getClass().getField("barRef").get(b);
147
if (aRef != null)
148
throw new RuntimeException("Expected null, got:" + aRef
149
+ ", in [" + b + "]");
150
} catch (NoSuchFieldException | IllegalAccessException x) {
151
throw new InternalError(x);
152
}
153
};
154
155
static void test_Foo() {
156
testFoo("Foo", "String", false, false, FOO_FIELDS_EQUAL); }
157
static void test_BadFoo() {
158
testFoo("BadFoo", "byte[]", true, false, FOO_FIELDS_DEFAULT); }
159
static void test_FooWithReadObject() {
160
testFoo("FooWithReadObject", "String", false, true, FOO_FIELDS_EQUAL); }
161
static void test_BadFooWithReadObject() {
162
testFoo("BadFooWithReadObject", "byte[]", true, true, FOO_FIELDS_DEFAULT); }
163
164
static void testFoo(String testName, String xyzZebraType,
165
boolean expectCCE, boolean withReadObject,
166
BiConsumer<Object,Object>... resultCheckers) {
167
System.out.println("\nTesting " + testName);
168
try {
169
Path testRoot = testDir(testName);
170
Path srcRoot = Files.createDirectory(testRoot.resolve("src"));
171
List<Path> srcFiles = new ArrayList<>();
172
srcFiles.add(createSrc(PKGS[0], fooTemplate, srcRoot, "String", withReadObject));
173
srcFiles.add(createSrc(PKGS[1], fooTemplate, srcRoot, xyzZebraType, withReadObject));
174
175
Path build = Files.createDirectory(testRoot.resolve("build"));
176
javac(build, srcFiles);
177
178
URLClassLoader loader = new URLClassLoader(new URL[]{ build.toUri().toURL() },
179
FailureAtomicity.class.getClassLoader());
180
Class<?> fooClass = Class.forName(PKGS[0] + ".Foo", true, loader);
181
Constructor<?> ctr = fooClass.getConstructor(
182
new Class<?>[]{int.class, String.class, String.class});
183
Object abcFoo = ctr.newInstance(5, "chegar", "zebra");
184
185
try {
186
toOtherPkgInstance(abcFoo, loader);
187
if (expectCCE)
188
throw new AssertionError("Expected CCE not thrown");
189
} catch (ClassCastException e) {
190
if (!expectCCE)
191
throw new AssertionError("UnExpected CCE: " + e);
192
}
193
194
Object deserialInstance = failureAtomicity.SerialRef.obj;
195
196
System.out.println("abcFoo: " + abcFoo);
197
System.out.println("deserialInstance: " + deserialInstance);
198
199
for (BiConsumer<Object, Object> rc : resultCheckers)
200
rc.accept(abcFoo, deserialInstance);
201
} catch (IOException x) {
202
throw new UncheckedIOException(x);
203
} catch (ReflectiveOperationException x) {
204
throw new InternalError(x);
205
}
206
}
207
208
static void test_Foo_Bar() {
209
testFooBar("Foo_Bar", "String", "String", false, false, false,
210
FOO_FIELDS_EQUAL, BAR_FIELDS_EQUAL);
211
}
212
static void test_Foo_BadBar() {
213
testFooBar("Foo_BadBar", "String", "byte[]", true, false, false,
214
FOO_FIELDS_DEFAULT, BAR_FIELDS_DEFAULT);
215
}
216
static void test_BadFoo_Bar() {
217
testFooBar("BadFoo_Bar", "byte[]", "String", true, false, false,
218
FOO_FIELDS_DEFAULT, BAR_FIELDS_DEFAULT);
219
}
220
static void test_BadFoo_BadBar() {
221
testFooBar("BadFoo_BadBar", "byte[]", "byte[]", true, false, false,
222
FOO_FIELDS_DEFAULT, BAR_FIELDS_DEFAULT);
223
}
224
static void test_Foo_BarWithReadObject() {
225
testFooBar("Foo_BarWithReadObject", "String", "String", false, false, true,
226
FOO_FIELDS_EQUAL, BAR_FIELDS_EQUAL);
227
}
228
static void test_Foo_BadBarWithReadObject() {
229
testFooBar("Foo_BadBarWithReadObject", "String", "byte[]", true, false, true,
230
FOO_FIELDS_EQUAL, BAR_FIELDS_DEFAULT);
231
}
232
static void test_BadFoo_BarWithReadObject() {
233
testFooBar("BadFoo_BarWithReadObject", "byte[]", "String", true, false, true,
234
FOO_FIELDS_DEFAULT, BAR_FIELDS_DEFAULT);
235
}
236
static void test_BadFoo_BadBarWithReadObject() {
237
testFooBar("BadFoo_BadBarWithReadObject", "byte[]", "byte[]", true, false, true,
238
FOO_FIELDS_DEFAULT, BAR_FIELDS_DEFAULT);
239
}
240
241
static void test_FooWithReadObject_Bar() {
242
testFooBar("FooWithReadObject_Bar", "String", "String", false, true, false,
243
FOO_FIELDS_EQUAL, BAR_FIELDS_EQUAL);
244
}
245
static void test_FooWithReadObject_BadBar() {
246
testFooBar("FooWithReadObject_BadBar", "String", "byte[]", true, true, false,
247
FOO_FIELDS_EQUAL, BAR_FIELDS_DEFAULT);
248
}
249
static void test_BadFooWithReadObject_Bar() {
250
testFooBar("BadFooWithReadObject_Bar", "byte[]", "String", true, true, false,
251
FOO_FIELDS_DEFAULT, BAR_FIELDS_DEFAULT);
252
}
253
static void test_BadFooWithReadObject_BadBar() {
254
testFooBar("BadFooWithReadObject_BadBar", "byte[]", "byte[]", true, true, false,
255
FOO_FIELDS_DEFAULT, BAR_FIELDS_DEFAULT);
256
}
257
258
static void testFooBar(String testName, String xyzFooZebraType,
259
String xyzBarZebraType, boolean expectCCE,
260
boolean fooWithReadObject, boolean barWithReadObject,
261
BiConsumer<Object,Object>... resultCheckers) {
262
System.out.println("\nTesting " + testName);
263
try {
264
Path testRoot = testDir(testName);
265
Path srcRoot = Files.createDirectory(testRoot.resolve("src"));
266
List<Path> srcFiles = new ArrayList<>();
267
srcFiles.add(createSrc(PKGS[0], fooTemplate, srcRoot, "String",
268
fooWithReadObject, "String"));
269
srcFiles.add(createSrc(PKGS[1], fooTemplate, srcRoot, xyzFooZebraType,
270
fooWithReadObject, xyzFooZebraType));
271
srcFiles.add(createSrc(PKGS[0], barTemplate, srcRoot, "String",
272
barWithReadObject, "String"));
273
srcFiles.add(createSrc(PKGS[1], barTemplate, srcRoot, xyzBarZebraType,
274
barWithReadObject, xyzFooZebraType));
275
276
Path build = Files.createDirectory(testRoot.resolve("build"));
277
javac(build, srcFiles);
278
279
URLClassLoader loader = new URLClassLoader(new URL[]{ build.toUri().toURL() },
280
FailureAtomicity.class.getClassLoader());
281
Class<?> fooClass = Class.forName(PKGS[0] + ".Bar", true, loader);
282
Constructor<?> ctr = fooClass.getConstructor(
283
new Class<?>[]{int.class, String.class, String.class,
284
long.class, String.class, String.class});
285
Object abcBar = ctr.newInstance( 5, "chegar", "zebraFoo", 111L, "aBar", "zebraBar");
286
287
try {
288
toOtherPkgInstance(abcBar, loader);
289
if (expectCCE)
290
throw new AssertionError("Expected CCE not thrown");
291
} catch (ClassCastException e) {
292
if (!expectCCE)
293
throw new AssertionError("UnExpected CCE: " + e);
294
}
295
296
Object deserialInstance = failureAtomicity.SerialRef.obj;
297
298
System.out.println("abcBar: " + abcBar);
299
System.out.println("deserialInstance: " + deserialInstance);
300
301
for (BiConsumer<Object, Object> rc : resultCheckers)
302
rc.accept(abcBar, deserialInstance);
303
} catch (IOException x) {
304
throw new UncheckedIOException(x);
305
} catch (ReflectiveOperationException x) {
306
throw new InternalError(x);
307
}
308
}
309
310
static Path testDir(String name) throws IOException {
311
Path testRoot = Paths.get("FailureAtomicity-" + name);
312
if (Files.exists(testRoot))
313
FileUtils.deleteFileTreeWithRetry(testRoot);
314
Files.createDirectory(testRoot);
315
return testRoot;
316
}
317
318
static String platformPath(String p) { return p.replace("/", File.separator); }
319
static String binaryName(String name) { return name.replace(".", "/"); }
320
static String condRemove(String line, String pattern, boolean hasReadObject) {
321
if (hasReadObject) { return line.replaceAll(pattern, ""); }
322
else { return line; }
323
}
324
static String condReplace(String line, String... zebraFooType) {
325
if (zebraFooType.length == 1) {
326
return line.replaceAll("\\$foo_zebra_type", zebraFooType[0]);
327
} else { return line; }
328
}
329
static String nameFromTemplate(Path template) {
330
return template.getFileName().toString().replaceAll(".template", "");
331
}
332
333
static Path createSrc(String pkg, Path srcTemplate, Path srcRoot,
334
String zebraType, boolean hasReadObject,
335
String... zebraFooType)
336
throws IOException
337
{
338
Path srcDst = srcRoot.resolve(platformPath(binaryName(pkg)));
339
Files.createDirectories(srcDst);
340
Path srcFile = srcDst.resolve(nameFromTemplate(srcTemplate) + ".java");
341
342
List<String> lines = Files.lines(srcTemplate)
343
.map(s -> s.replaceAll("\\$package", pkg))
344
.map(s -> s.replaceAll("\\$zebra_type", zebraType))
345
.map(s -> condReplace(s, zebraFooType))
346
.map(s -> condRemove(s, "//\\$has_readObject", hasReadObject))
347
.collect(Collectors.toList());
348
Files.write(srcFile, lines);
349
return srcFile;
350
}
351
352
static void javac(Path dest, List<Path> sourceFiles) throws IOException {
353
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
354
try (StandardJavaFileManager fileManager =
355
compiler.getStandardFileManager(null, null, null)) {
356
List<File> files = sourceFiles.stream()
357
.map(p -> p.toFile())
358
.collect(Collectors.toList());
359
Iterable<? extends JavaFileObject> compilationUnits =
360
fileManager.getJavaFileObjectsFromFiles(files);
361
fileManager.setLocation(StandardLocation.CLASS_OUTPUT,
362
Arrays.asList(dest.toFile()));
363
fileManager.setLocation(StandardLocation.CLASS_PATH,
364
Arrays.asList(TEST_CLASSES.toFile()));
365
JavaCompiler.CompilationTask task = compiler
366
.getTask(null, fileManager, null, null, null, compilationUnits);
367
boolean passed = task.call();
368
if (!passed)
369
throw new RuntimeException("Error compiling " + files);
370
}
371
}
372
373
static Object toOtherPkgInstance(Object obj, ClassLoader loader)
374
throws IOException, ClassNotFoundException
375
{
376
byte[] bytes = serialize(obj);
377
bytes = replacePkg(bytes);
378
return deserialize(bytes, loader);
379
}
380
381
@SuppressWarnings("deprecation")
382
static byte[] replacePkg(byte[] bytes) {
383
String str = new String(bytes, 0);
384
str = str.replaceAll(PKGS[0], PKGS[1]);
385
str.getBytes(0, bytes.length, bytes, 0);
386
return bytes;
387
}
388
389
static byte[] serialize(Object obj) throws IOException {
390
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
391
ObjectOutputStream out = new ObjectOutputStream(baos);) {
392
out.writeObject(obj);
393
return baos.toByteArray();
394
}
395
}
396
397
static Object deserialize(byte[] data, ClassLoader l)
398
throws IOException, ClassNotFoundException
399
{
400
return new WithLoaderObjectInputStream(new ByteArrayInputStream(data), l)
401
.readObject();
402
}
403
404
static class WithLoaderObjectInputStream extends ObjectInputStream {
405
final ClassLoader loader;
406
WithLoaderObjectInputStream(InputStream is, ClassLoader loader)
407
throws IOException
408
{
409
super(is);
410
this.loader = loader;
411
}
412
@Override
413
protected Class<?> resolveClass(ObjectStreamClass desc)
414
throws IOException, ClassNotFoundException {
415
try {
416
return super.resolveClass(desc);
417
} catch (ClassNotFoundException x) {
418
String name = desc.getName();
419
return Class.forName(name, false, loader);
420
}
421
}
422
}
423
}
424
425