1 /******************************************************************************* 2 * Copyright (c) 2014, 2017 GoPivotal, Inc. and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for 13 * Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas 14 * Bug 439889 - [1.8][compiler] [lambda] Deserializing lambda fails with IllegalArgumentException: "Invalid lambda deserialization" 15 * Bug 442416 - $deserializeLambda$ missing cases for nested lambdas 16 * Bug 442418 - $deserializeLambda$ off-by-one error when deserializing the captured arguments of a lambda that also capture this 17 * Bug 449467 - [1.8][compiler] Invalid lambda deserialization with anonymous class 18 * Olivier Tardieu tardieu@us.ibm.com - Contributions for 19 * Bug 442416 - $deserializeLambda$ missing cases for nested lambdas 20 * Bug 442418 - $deserializeLambda$ off-by-one error when deserializing the captured arguments of a lambda that also capture this 21 * IBM Corporation - Additional tests 22 *******************************************************************************/ 23 package org.eclipse.jdt.core.tests.compiler.regression; 24 25 import java.io.File; 26 import java.lang.reflect.Modifier; 27 import java.util.Map; 28 29 import org.eclipse.jdt.core.ToolFactory; 30 import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; 31 import org.eclipse.jdt.core.util.IBootstrapMethodsEntry; 32 import org.eclipse.jdt.core.util.IClassFileAttribute; 33 import org.eclipse.jdt.core.util.IClassFileReader; 34 import org.eclipse.jdt.core.util.IConstantPool; 35 import org.eclipse.jdt.core.util.IConstantPoolConstant; 36 import org.eclipse.jdt.core.util.IConstantPoolEntry; 37 import org.eclipse.jdt.core.util.IConstantPoolEntry2; 38 import org.eclipse.jdt.core.util.IMethodInfo; 39 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; 40 import org.eclipse.jdt.internal.core.util.BootstrapMethodsAttribute; 41 42 import junit.framework.Test; 43 44 @SuppressWarnings({ "unchecked", "rawtypes" }) 45 public class SerializableLambdaTest extends AbstractRegressionTest { 46 47 static { 48 // TESTS_NUMBERS = new int [] { 40 }; 49 // TESTS_NAMES = new String[] { "testTypeVariable" }; 50 } 51 testClass()52 public static Class testClass() { 53 return SerializableLambdaTest.class; 54 } suite()55 public static Test suite() { 56 return buildMinimalComplianceTestSuite(testClass(), F_1_8); 57 } SerializableLambdaTest(String testName)58 public SerializableLambdaTest(String testName){ 59 super(testName); 60 } 61 62 // Enables the tests to run individually 63 @Override getCompilerOptions()64 protected Map getCompilerOptions() { 65 Map defaultOptions = super.getCompilerOptions(); 66 defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8); 67 defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8); 68 defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8); 69 return defaultOptions; 70 } 71 72 public static final String RUNNER_CLASS = 73 "public class Y {\n"+ 74 " public static void main(String[]args) {\n"+ 75 " com.foo.X.main(args);\n"+ 76 " }\n"+ 77 "}"; 78 79 private static final String HELPER_CLASS = 80 "package util;\n"+ 81 "import java.io.*;\n"+ 82 "public class Helper {\n"+ 83 "public static void print(Object o ) {System.err.println(o);}\n"+ 84 "static byte[][] data;\n"+ 85 "\n"+ 86 "public static void write(Object o) { write(0,o); }\n"+ 87 "public static void write(int i, Object o) {\n"+ 88 " if (data==null) data=new byte[10][];\n"+ 89 " try {\n"+ 90 " ByteArrayOutputStream baos = new ByteArrayOutputStream();\n"+ 91 " ObjectOutputStream oos = new ObjectOutputStream(baos);\n"+ 92 " oos.writeObject(o);\n"+ 93 " oos.flush();\n"+ 94 " oos.close();\n"+ 95 " data[i] = baos.toByteArray();\n"+ 96 " } catch (Exception e) {\n"+ 97 " }\n"+ 98 "}\n"+ 99 "\n"+ 100 "public static Object read() { return read(0); }\n"+ 101 "public static Object read(int i) {\n"+ 102 " try {\n"+ 103 " ByteArrayInputStream bais = new ByteArrayInputStream(data[i]);\n"+ 104 " ObjectInputStream ois = new ObjectInputStream(bais);\n"+ 105 " Object o = ois.readObject();\n"+ 106 " ois.close();\n"+ 107 " return o;\n"+ 108 " } catch (Exception e) {\n"+ 109 " }\n"+ 110 " return null;\n"+ 111 "}\n"+ 112 "}\n"; 113 114 /** 115 * Verifies that after deserializing it is usable, also that the bootstrap methods attribute indicates use of altMetafactory 116 */ test001_simple()117 public void test001_simple() throws Exception { 118 this.runConformTest( 119 new String[]{ 120 "X.java", 121 "import java.io.*;\n"+ 122 "public class X {\n"+ 123 " interface Foo extends Serializable { int m(); }\n"+ 124 "\n"+ 125 " public static void main(String[] args) {\n"+ 126 " Foo f1 = null;\n"+ 127 " f1 = () -> 3;\n"+ 128 " util.Helper.write(f1);\n"+ 129 " f1 = (Foo)util.Helper.read();\n"+ 130 " System.out.println(f1.m());\n"+ 131 " }\n"+ 132 "}\n", 133 "Helper.java",HELPER_CLASS, 134 }, 135 "3", 136 null, 137 true, 138 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 139 String expectedOutput = 140 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 141 " Method arguments:\n"+ 142 " ()I\n"+ 143 " invokestatic X.lambda$0:()I\n"+ 144 " ()I\n"+ 145 " 1\n"; 146 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 147 checkExpected(expectedOutput,data); 148 } 149 150 /** 151 * Sanity test, non serializable should have bootstrap methods attribute reference to metafactory. 152 */ test002_simpleNonSerializable()153 public void test002_simpleNonSerializable() throws Exception { 154 this.runConformTest( 155 new String[]{ 156 "X.java", 157 "import java.io.*;\n"+ 158 "public class X {\n"+ 159 " interface Foo { int m(); }\n"+ 160 "\n"+ 161 " public static void main(String[] args) {\n"+ 162 " Foo f1 = null;\n"+ 163 " f1 = () -> 3;\n"+ 164 " System.out.println(f1.m());\n"+ 165 " }\n"+ 166 "}\n", 167 "Helper.java",HELPER_CLASS, 168 }, 169 "3"); 170 String expectedOutput = 171 "0: invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;\n"+ 172 " Method arguments:\n"+ 173 " ()I\n"+ 174 " invokestatic X.lambda$0:()I\n"+ 175 " ()I\n"; 176 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 177 checkExpected(expectedOutput,data); 178 } 179 180 /** 181 * Basic test that deserializeLambda can cope with two lambda expressions. 182 */ test003_twoSerializedLambdas()183 public void test003_twoSerializedLambdas() throws Exception { 184 this.runConformTest( 185 new String[]{ 186 "X.java", 187 "import java.io.*;\n"+ 188 "public class X {\n"+ 189 " interface Foo extends Serializable { int m(); }\n"+ 190 "\n"+ 191 " public static void main(String[] args) {\n"+ 192 " Foo f1 = null, f2 = null;\n"+ 193 " f1 = () -> 33;\n"+ 194 " f2 = () -> 99;\n"+ 195 " util.Helper.write(0,f1);\n"+ 196 " util.Helper.write(1,f2);\n"+ 197 " f2 = (Foo)util.Helper.read(1);\n"+ 198 " f1 = (Foo)util.Helper.read(0);\n"+ 199 " System.out.println(f1.m());\n"+ 200 " System.out.println(f2.m());\n"+ 201 " }\n"+ 202 "}\n", 203 "Helper.java",HELPER_CLASS, 204 }, 205 "33\n99", 206 null, 207 true, 208 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 209 String expectedOutput = 210 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 211 " Method arguments:\n"+ 212 " ()I\n"+ 213 " invokestatic X.lambda$0:()I\n"+ 214 " ()I\n"+ 215 " 1\n"+ 216 "1: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 217 " Method arguments:\n"+ 218 " ()I\n"+ 219 " invokestatic X.lambda$1:()I\n"+ 220 " ()I\n"+ 221 " 1\n"; 222 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 223 checkExpected(expectedOutput,data); 224 } 225 test004_lambdaWithParameterInPackage()226 public void test004_lambdaWithParameterInPackage() throws Exception { 227 this.runConformTest( 228 new String[]{ 229 "Y.java", 230 "public class Y {\n"+ 231 " public static void main(String[]args) {\n"+ 232 " com.foo.X.main(args);\n"+ 233 " }\n"+ 234 "}", 235 "X.java", 236 "package com.foo;\n"+ 237 "import java.io.*;\n"+ 238 "public class X {\n"+ 239 " interface Foo extends Serializable { int m(int i); }\n"+ 240 "\n"+ 241 " public static void main(String[] args) {\n"+ 242 " Foo f1 = null, f2 = null;\n"+ 243 " f1 = (i) -> i*2;\n"+ 244 " util.Helper.write(f1);\n"+ 245 " f1 = (Foo)util.Helper.read();\n"+ 246 " System.out.println(f1.m(4));\n"+ 247 " }\n"+ 248 "}\n", 249 "Helper.java",HELPER_CLASS, 250 }, 251 "8", 252 null, 253 true, 254 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 255 String expectedOutput = 256 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 257 " Method arguments:\n"+ 258 " (I)I\n"+ 259 " invokestatic com/foo/X.lambda$0:(I)I\n"+ 260 " (I)I\n"+ 261 " 1\n"; 262 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "com"+File.separator+"foo"+File.separator+"X.class"); 263 checkExpected(expectedOutput,data); 264 } 265 test005_capturingVariableLambdaWithParameterInPackage()266 public void test005_capturingVariableLambdaWithParameterInPackage() throws Exception { 267 this.runConformTest( 268 new String[]{ 269 "Y.java", 270 "public class Y {\n"+ 271 " public static void main(String[]args) {\n"+ 272 " com.foo.X.main(args);\n"+ 273 " }\n"+ 274 "}", 275 "X.java", 276 "package com.foo;\n"+ 277 "import java.io.*;\n"+ 278 "public class X {\n"+ 279 " interface Foo extends Serializable { int m(int i); }\n"+ 280 "\n"+ 281 " public static void main(String[] args) {\n"+ 282 " Foo f1 = null;\n"+ 283 " int multiplier = 3;\n"+ 284 " f1 = (i) -> i * multiplier;\n"+ 285 " util.Helper.write(f1);\n"+ 286 " f1 = (Foo)util.Helper.read();\n"+ 287 " System.out.println(f1.m(4));\n"+ 288 " }\n"+ 289 "}\n", 290 "Helper.java",HELPER_CLASS, 291 }, 292 "12", 293 null, 294 true, 295 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 296 String expectedOutput = 297 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 298 " Method arguments:\n"+ 299 " (I)I\n"+ 300 " invokestatic com/foo/X.lambda$0:(II)I\n"+ 301 " (I)I\n"+ 302 " 1\n"; 303 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "com"+File.separator+"foo"+File.separator+"X.class"); 304 checkExpected(expectedOutput,data); 305 } 306 307 // differing types, not just int test006_capturingVariableLambdaWithParameterInPackage()308 public void test006_capturingVariableLambdaWithParameterInPackage() throws Exception { 309 this.runConformTest( 310 new String[]{ 311 "Y.java", 312 "public class Y {\n"+ 313 " public static void main(String[]args) {\n"+ 314 " com.foo.X.main(args);\n"+ 315 " }\n"+ 316 "}", 317 "X.java", 318 "package com.foo;\n"+ 319 "import java.io.*;\n"+ 320 "public class X {\n"+ 321 " interface Foo extends Serializable { int m(String n); }\n"+ 322 "\n"+ 323 " public static void main(String[] args) {\n"+ 324 " Foo f1 = null;\n"+ 325 " int multiplier = 3;\n"+ 326 " f1 = (n) -> Integer.valueOf(n) * multiplier;\n"+ 327 " util.Helper.write(f1);\n"+ 328 " f1 = (Foo)util.Helper.read();\n"+ 329 " System.out.println(f1.m(\"33\"));\n"+ 330 " }\n"+ 331 "}\n", 332 "Helper.java",HELPER_CLASS, 333 }, 334 "99", 335 null, 336 true, 337 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 338 String expectedOutput = 339 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 340 " Method arguments:\n"+ 341 " (Ljava/lang/String;)I\n"+ 342 " invokestatic com/foo/X.lambda$0:(ILjava/lang/String;)I\n"+ 343 " (Ljava/lang/String;)I\n"+ 344 " 1\n"; 345 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "com"+File.separator+"foo"+File.separator+"X.class"); 346 checkExpected(expectedOutput,data); 347 } 348 349 // Fails the same way as javac right now... with NPE (b120) xtest007_capturingFieldLambdaWithParameterInPackage()350 public void xtest007_capturingFieldLambdaWithParameterInPackage() throws Exception { 351 this.runConformTest( 352 new String[]{ 353 "Y.java", 354 "public class Y {\n"+ 355 " public static void main(String[]args) {\n"+ 356 " com.foo.X.main(args);\n"+ 357 " }\n"+ 358 "}", 359 "X.java", 360 "package com.foo;\n"+ 361 "import java.io.*;\n"+ 362 "public class X {\n"+ 363 " int multiplier = 3;\n"+ 364 " interface Foo extends Serializable { int m(int i); }\n"+ 365 "\n"+ 366 " public static void main(String[] args) {\n"+ 367 " new X().run();\n"+ 368 " }\n"+ 369 " public void run() {\n"+ 370 " Foo f1 = null;\n"+ 371 " f1 = (i) -> i * this.multiplier;\n"+ 372 " util.Helper.write(f1);\n"+ 373 " f1 = (Foo)util.Helper.read();\n"+ 374 " System.out.println(f1.m(4));\n"+ 375 " }\n"+ 376 "}\n", 377 "Helper.java",HELPER_CLASS, 378 }, 379 "12", 380 null, 381 true, 382 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 383 String expectedOutput = 384 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 385 " Method arguments:\n"+ 386 " (I)I\n"+ 387 " invokestatic com/foo/X.lambda$0:(II)I\n"+ 388 " (I)I\n"+ 389 " 1\n"; 390 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "com"+File.separator+"foo"+File.separator+"X.class"); 391 checkExpected(expectedOutput,data); 392 } 393 test008_capturingTwoVariableLambdaWithParameterInPackage()394 public void test008_capturingTwoVariableLambdaWithParameterInPackage() throws Exception { 395 this.runConformTest( 396 new String[]{ 397 "Y.java", 398 "public class Y {\n"+ 399 " public static void main(String[]args) {\n"+ 400 " com.foo.X.main(args);\n"+ 401 " }\n"+ 402 "}", 403 "X.java", 404 "package com.foo;\n"+ 405 "import java.io.*;\n"+ 406 "public class X {\n"+ 407 " interface Foo extends Serializable { float m(int i, float f); }\n"+ 408 "\n"+ 409 " public static void main(String[] args) {\n"+ 410 " new X().run();\n"+ 411 " }\n"+ 412 " public void run() {\n"+ 413 " Foo f1 = null;\n"+ 414 " f1 = (i,f) -> ((float)i) * f;\n"+ 415 " util.Helper.write(f1);\n"+ 416 " f1 = (Foo)util.Helper.read();\n"+ 417 " System.out.println(f1.m(3,4.0f));\n"+ 418 " }\n"+ 419 "}\n", 420 "Helper.java",HELPER_CLASS, 421 }, 422 "12.0", 423 null, 424 true, 425 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 426 String expectedOutput = 427 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 428 " Method arguments:\n"+ 429 " (IF)F\n"+ 430 " invokestatic com/foo/X.lambda$0:(IF)F\n"+ 431 " (IF)F\n"+ 432 " 1\n"; 433 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "com"+File.separator+"foo"+File.separator+"X.class"); 434 checkExpected(expectedOutput,data); 435 } 436 test009_capturingTwoSlotVariablesLambdaWithParameterInPackage()437 public void test009_capturingTwoSlotVariablesLambdaWithParameterInPackage() throws Exception { 438 this.runConformTest( 439 new String[]{ 440 "Y.java",RUNNER_CLASS, 441 "X.java", 442 "package com.foo;\n"+ 443 "import java.io.*;\n"+ 444 "public class X {\n"+ 445 " interface Foo extends Serializable { double m(int i, long l); }\n"+ 446 "\n"+ 447 " public static void main(String[] args) {\n"+ 448 " new X().run();\n"+ 449 " }\n"+ 450 " public void run() {\n"+ 451 " Foo f1 = null;\n"+ 452 " f1 = (i,l) -> (double)(i*l);\n"+ 453 " util.Helper.write(f1);\n"+ 454 " f1 = (Foo)util.Helper.read();\n"+ 455 " System.out.println(f1.m(3,40L));\n"+ 456 " }\n"+ 457 "}\n", 458 "Helper.java",HELPER_CLASS, 459 }, 460 "120.0", 461 null, 462 true, 463 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 464 String expectedOutput = 465 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 466 " Method arguments:\n"+ 467 " (IJ)D\n"+ 468 " invokestatic com/foo/X.lambda$0:(IJ)D\n"+ 469 " (IJ)D\n"+ 470 " 1\n"; 471 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "com"+File.separator+"foo"+File.separator+"X.class"); 472 checkExpected(expectedOutput,data); 473 } 474 test010_VarargsLambdaExpression()475 public void test010_VarargsLambdaExpression() throws Exception { 476 this.runConformTest( 477 new String[]{ 478 "Y.java",RUNNER_CLASS, 479 "X.java", 480 "package com.foo;\n"+ 481 "import java.io.*;\n"+ 482 "public class X {\n"+ 483 " interface Foo extends Serializable { String m(String... ss); }\n"+ 484 "\n"+ 485 " public static void main(String[] args) {\n"+ 486 " new X().run();\n"+ 487 " }\n"+ 488 " public void run() {\n"+ 489 " Foo f1 = null;\n"+ 490 " f1 = (strings) -> strings[0]+strings[1];\n"+ 491 " util.Helper.write(f1);\n"+ 492 " f1 = (Foo)util.Helper.read();\n"+ 493 " System.out.println(f1.m(\"abc\",\"def\"));\n"+ 494 " }\n"+ 495 "}\n", 496 "Helper.java",HELPER_CLASS, 497 }, 498 "abcdef", 499 null, 500 true, 501 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 502 String expectedOutput = 503 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 504 " Method arguments:\n"+ 505 " ([Ljava/lang/String;)Ljava/lang/String;\n"+ 506 " invokestatic com/foo/X.lambda$0:([Ljava/lang/String;)Ljava/lang/String;\n"+ 507 " ([Ljava/lang/String;)Ljava/lang/String;\n"+ 508 " 1\n"; 509 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "com"+File.separator+"foo"+File.separator+"X.class"); 510 checkExpected(expectedOutput,data); 511 } 512 513 // Fails same way as javac right now... with an NPE (b120) xtest011_CapturingInstance()514 public void xtest011_CapturingInstance() throws Exception { 515 this.runConformTest( 516 new String[]{ 517 "Y.java",RUNNER_CLASS, 518 "X.java", 519 "package com.foo;\n"+ 520 "import java.io.*;\n"+ 521 "public class X {\n"+ 522 " interface Foo extends Serializable { String m(); }\n"+ 523 "\n"+ 524 " String fieldValue = \"hello\";\n"+ 525 " public static void main(String[] args) {\n"+ 526 " new X().run();\n"+ 527 " }\n"+ 528 " public void run() {\n"+ 529 " Foo f1 = null;\n"+ 530 " f1 = () -> this.fieldValue;\n"+ 531 " util.Helper.write(f1);\n"+ 532 " f1 = (Foo)util.Helper.read();\n"+ 533 " System.out.println(f1.m());\n"+ 534 " }\n"+ 535 "}\n", 536 "Helper.java",HELPER_CLASS, 537 }, 538 "abcdef", 539 null, 540 true, 541 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 542 String expectedOutput = 543 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 544 " Method arguments:\n"+ 545 " ([Ljava/lang/String;)Ljava/lang/String;\n"+ 546 " invokestatic com/foo/X.lambda$0:([Ljava/lang/String;)Ljava/lang/String;\n"+ 547 " ([Ljava/lang/String;)Ljava/lang/String;\n"+ 548 " 1\n"; 549 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "com"+File.separator+"foo"+File.separator+"X.class"); 550 checkExpected(expectedOutput,data); 551 } 552 test012_intersectionCast()553 public void test012_intersectionCast() throws Exception { 554 this.runConformTest( 555 new String[]{ 556 "X.java", 557 "import java.io.*;\n"+ 558 "public class X {\n"+ 559 " interface Foo extends Serializable { int m(); }\n"+ 560 " interface Marker {}\n"+ 561 "\n"+ 562 " public static void main(String[] args) {\n"+ 563 " Foo f1 = null;\n"+ 564 " f1 = (Foo & Marker) () -> 3;\n"+ 565 " System.out.println(\"isMarker?\"+(f1 instanceof Marker));\n"+ 566 " util.Helper.write(f1);\n"+ 567 " f1 = (Foo)util.Helper.read();\n"+ 568 " System.out.println(f1.m());\n"+ 569 " System.out.println(\"isMarker?\"+(f1 instanceof Marker));\n"+ 570 " }\n"+ 571 "}\n", 572 "Helper.java",HELPER_CLASS, 573 }, 574 "isMarker?true\n3\nisMarker?true", 575 null, 576 true, 577 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 578 String expectedOutput = 579 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 580 " Method arguments:\n"+ 581 " ()I\n"+ 582 " invokestatic X.lambda$0:()I\n"+ 583 " ()I\n"+ 584 " 3\n"+ // BitFlags: 0x01 = FLAG_SERIALIZABLE 0x02 = FLAG_MARKER 585 " 1\n"+ // Marker interface count 586 " X$Marker\n"; 587 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 588 checkExpected(expectedOutput,data); 589 } 590 test013_intersectionCast()591 public void test013_intersectionCast() throws Exception { 592 this.runConformTest( 593 new String[]{ 594 "X.java", 595 "import java.io.*;\n"+ 596 "interface Goo {}\n"+ 597 "public class X {\n"+ 598 " interface Foo extends Serializable { int m(); }\n"+ 599 " interface Marker {}\n"+ 600 "\n"+ 601 " public static void main(String[] args) {\n"+ 602 " Foo f1 = null;\n"+ 603 " f1 = (Foo & Goo & Serializable & Marker) () -> 3;\n"+ 604 " System.out.println(\"isMarker?\"+(f1 instanceof Marker));\n"+ 605 " System.out.println(\"isGoo?\"+(f1 instanceof Goo));\n"+ 606 " System.out.println(\"isSerializable?\"+(f1 instanceof Serializable));\n"+ 607 " util.Helper.write(f1);\n"+ 608 " f1 = (Foo)util.Helper.read();\n"+ 609 " System.out.println(f1.m());\n"+ 610 " System.out.println(\"isMarker?\"+(f1 instanceof Marker));\n"+ 611 " System.out.println(\"isGoo?\"+(f1 instanceof Goo));\n"+ 612 " System.out.println(\"isSerializable?\"+(f1 instanceof Serializable));\n"+ 613 " }\n"+ 614 "}\n", 615 "Helper.java",HELPER_CLASS, 616 }, 617 "isMarker?true\nisGoo?true\nisSerializable?true\n3\nisMarker?true\nisGoo?true\nisSerializable?true", 618 null, 619 true, 620 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 621 String expectedOutput = 622 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 623 " Method arguments:\n"+ 624 " ()I\n"+ 625 " invokestatic X.lambda$0:()I\n"+ 626 " ()I\n"+ 627 " 3\n"+ // BitFlags: 0x01 = FLAG_SERIALIZABLE 0x02 = FLAG_MARKER 628 " 2\n"+ // Marker interface count 629 " Goo\n"+ 630 " X$Marker\n"; 631 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 632 checkExpected(expectedOutput,data); 633 } 634 test014_intersectionCastAndNotSerializable()635 public void test014_intersectionCastAndNotSerializable() throws Exception { 636 this.runConformTest( 637 new String[]{ 638 "X.java", 639 "import java.io.*;\n"+ 640 "interface Goo {}\n"+ 641 "public class X {\n"+ 642 " interface Foo { int m(); }\n"+ 643 " interface Marker {}\n"+ 644 "\n"+ 645 " public static void main(String[] args) {\n"+ 646 " Foo f1 = null;\n"+ 647 " f1 = (Foo & Goo & Marker) () -> 3;\n"+ 648 " System.out.println(\"isMarker?\"+(f1 instanceof Marker));\n"+ 649 " System.out.println(\"isGoo?\"+(f1 instanceof Goo));\n"+ 650 " System.out.println(\"isSerializable?\"+(f1 instanceof Serializable));\n"+ 651 " System.out.println(f1.m());\n"+ 652 " }\n"+ 653 "}\n", 654 "Helper.java",HELPER_CLASS, 655 }, 656 "isMarker?true\nisGoo?true\nisSerializable?false\n3", 657 null, 658 true, 659 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 660 String expectedOutput = 661 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 662 " Method arguments:\n"+ 663 " ()I\n"+ 664 " invokestatic X.lambda$0:()I\n"+ 665 " ()I\n"+ 666 " 2\n"+ // BitFlags: 0x02 = FLAG_MARKER 667 " 2\n"+ // Marker interface count 668 " Goo\n"+ 669 " X$Marker\n"; 670 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 671 checkExpected(expectedOutput,data); 672 } 673 test015_serializableViaIntersectionCast()674 public void test015_serializableViaIntersectionCast() throws Exception { 675 this.runConformTest( 676 new String[]{ 677 "X.java", 678 "import java.io.*;\n"+ 679 "interface Goo {}\n"+ 680 "public class X {\n"+ 681 " interface Foo { int m(); }\n"+ 682 " interface Marker {}\n"+ 683 "\n"+ 684 " public static void main(String[] args) {\n"+ 685 " Foo f1 = null;\n"+ 686 " f1 = (Foo & Goo & Serializable & Marker) () -> 3;\n"+ 687 " System.out.println(\"isMarker?\"+(f1 instanceof Marker));\n"+ 688 " System.out.println(\"isGoo?\"+(f1 instanceof Goo));\n"+ 689 " System.out.println(\"isSerializable?\"+(f1 instanceof Serializable));\n"+ 690 " util.Helper.write(f1);\n"+ 691 " f1 = (Foo)util.Helper.read();\n"+ 692 " System.out.println(f1.m());\n"+ 693 " System.out.println(\"isMarker?\"+(f1 instanceof Marker));\n"+ 694 " System.out.println(\"isGoo?\"+(f1 instanceof Goo));\n"+ 695 " System.out.println(\"isSerializable?\"+(f1 instanceof Serializable));\n"+ 696 " }\n"+ 697 "}\n", 698 "Helper.java",HELPER_CLASS, 699 }, 700 "isMarker?true\nisGoo?true\nisSerializable?true\n3\nisMarker?true\nisGoo?true\nisSerializable?true", 701 null, 702 true, 703 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 704 String expectedOutput = 705 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 706 " Method arguments:\n"+ 707 " ()I\n"+ 708 " invokestatic X.lambda$0:()I\n"+ 709 " ()I\n"+ 710 " 3\n"+ // BitFlags: 0x01 = FLAG_SERIALIZABLE 0x02 = FLAG_MARKER 711 " 2\n"+ // Marker interface count 712 " Goo\n"+ 713 " X$Marker\n"; 714 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 715 checkExpected(expectedOutput,data); 716 } 717 718 // SAM type not first in intersection cast test016_bug424211()719 public void test016_bug424211() throws Exception { 720 this.runConformTest( 721 new String[]{ 722 "X.java", 723 "import java.io.Serializable;\n"+ 724 "public class X {\n"+ 725 " public static void main(String argv[]) throws Exception {\n"+ 726 " AutoCloseable one = ((Serializable & AutoCloseable) (() -> {}));\n"+ 727 " one.close();\n"+ 728 " }\n"+ 729 "}" 730 }, 731 "", 732 null, 733 true, 734 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 735 String expectedOutput = 736 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 737 " Method arguments:\n"+ 738 " ()V\n"+ 739 " invokestatic X.lambda$0:()V\n"+ 740 " ()V\n"+ 741 " 1\n"; 742 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 743 checkExpected(expectedOutput,data); 744 } 745 746 // Now SAM type first test017_bug424211()747 public void test017_bug424211() throws Exception { 748 this.runConformTest( 749 new String[]{ 750 "X.java", 751 "import java.io.Serializable;\n"+ 752 "public class X {\n"+ 753 " public static void main(String argv[]) throws Exception {\n"+ 754 " AutoCloseable one = ((AutoCloseable & Serializable) (() -> {}));\n"+ 755 " one.close();\n"+ 756 " }\n"+ 757 "}" 758 }, 759 "", 760 null, 761 true, 762 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 763 String expectedOutput = 764 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 765 " Method arguments:\n"+ 766 " ()V\n"+ 767 " invokestatic X.lambda$0:()V\n"+ 768 " ()V\n"+ 769 " 1\n"; 770 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 771 checkExpected(expectedOutput,data); 772 } 773 774 // Not Serializable but a regular marker interface test018_bug424211()775 public void test018_bug424211() throws Exception { 776 this.runConformTest( 777 new String[]{ 778 "X.java", 779 "import java.io.Serializable;\n"+ 780 "interface Marker {}\n"+ 781 "public class X {\n"+ 782 " public static void main(String argv[]) throws Exception {\n"+ 783 " AutoCloseable one = ((Marker & AutoCloseable) (() -> {}));\n"+ 784 " one.close();\n"+ 785 " }\n"+ 786 "}" 787 }, 788 "", 789 null, 790 true, 791 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 792 String expectedOutput = 793 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 794 " Method arguments:\n"+ 795 " ()V\n"+ 796 " invokestatic X.lambda$0:()V\n"+ 797 " ()V\n"+ 798 " 2\n"+ 799 " 1\n"+ 800 " Marker\n"; 801 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 802 checkExpected(expectedOutput,data); 803 } 804 805 // Now SAM type not first and serialization occurring test019_bug424211()806 public void test019_bug424211() throws Exception { 807 this.runConformTest( 808 new String[]{ 809 "X.java", 810 "import java.io.Serializable;\n"+ 811 "interface SAM {int m();}\n"+ 812 "public class X {\n"+ 813 " public static void main(String argv[]) throws Exception {\n"+ 814 " SAM one = ((Serializable & SAM) (() -> 3));\n"+ 815 " System.out.println(one.m());\n"+ 816 " util.Helper.write(one);\n"+ 817 " one = (SAM)util.Helper.read();\n"+ 818 " System.out.println(one.m());\n"+ 819 " }\n"+ 820 "}", 821 "Helper.java",HELPER_CLASS, 822 }, 823 "3\n3", 824 null, 825 true, 826 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 827 String expectedOutput = 828 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 829 " Method arguments:\n"+ 830 " ()I\n"+ 831 " invokestatic X.lambda$0:()I\n"+ 832 " ()I\n"+ 833 " 1\n"; 834 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 835 checkExpected(expectedOutput,data); 836 } 837 test020_lambdaNames()838 public void test020_lambdaNames() throws Exception { 839 this.runConformTest( 840 new String[]{ 841 "X.java", 842 "import java.io.Serializable;\n"+ 843 "interface Foo {int m();}\n"+ 844 "interface FooN extends Serializable {int m();}\n"+ 845 "public class X {\n"+ 846 " public static void main(String argv[]) throws Exception {\n"+ 847 " AutoCloseable one = () -> {};\n"+ 848 " new X().m();\n"+ 849 " one.close();\n"+ 850 " }\n"+ 851 " public void m() { Foo f = () -> 3; System.out.println(f.m());}\n"+ 852 " public void n() { FooN f = () -> 3; System.out.println(f.m());}\n"+ 853 "}" 854 }, 855 "3", 856 null, 857 true, 858 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 859 String expectedOutput = 860 " private static synthetic void lambda$0() throws java.lang.Exception;\n"; 861 checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); 862 expectedOutput = 863 " private static synthetic int lambda$1();\n"; 864 checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM); 865 } 866 test021_lambdaNamesVariants()867 public void test021_lambdaNamesVariants() throws Exception { 868 this.runConformTest( 869 new String[]{ 870 "X.java", 871 "import java.io.Serializable;\n"+ 872 "interface Foo {int m();}\n"+ 873 "interface FooSer extends Serializable {int m();}\n"+ 874 "interface FooI {int m(int i);}\n"+ 875 "interface FooSerI extends Serializable {int m(int i);}\n"+ 876 "public class X {\n"+ 877 "\n"+ 878 " Foo instanceField = () -> 1;\n"+ 879 " FooSer instanceFieldSer = () -> 2;\n"+ 880 " static Foo staticField = () -> 3;\n"+ 881 " static FooSer staticFieldSer = () -> 4;\n"+ 882 " FooI instanceFieldI = (i) -> 5;\n"+ 883 " FooSerI instanceFieldSerI = (i) -> 6;\n"+ 884 "\n"+ 885 " public static void main(String argv[]) throws Exception {\n"+ 886 " int x = 4;\n"+ 887 " Foo a = () -> 1;\n"+ 888 " FooSer b = () -> 2;\n"+ 889 " FooI c = (i) -> 3;\n"+ 890 " FooSerI d = (i) -> 4;\n"+ 891 " Foo e = () -> x;\n"+ 892 " FooSer f = () -> x+1;\n"+ 893 " FooI g = (i) -> x+2;\n"+ 894 " FooSerI h = (i) -> x+3;\n"+ 895 " }\n"+ 896 "}" 897 }, 898 "", 899 null, 900 true, 901 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 902 String expectedOutput = 903 "static lambda$2()I\n"+ 904 "static lambda$3()I\n"+ 905 "static lambda$0()I\n"+ 906 "static lambda$1()I\n"+ 907 "static lambda$4(I)I\n"+ 908 "static lambda$5(I)I\n"+ 909 "static lambda$6()I\n"+ 910 "static lambda$7()I\n"+ 911 "static lambda$8(I)I\n"+ 912 "static lambda$9(I)I\n"+ 913 "static lambda$10(I)I\n"+ 914 "static lambda$11(I)I\n"+ 915 "static lambda$12(II)I\n"+ 916 "static lambda$13(II)I\n"; 917 String actualOutput = printLambdaMethods(OUTPUT_DIR + File.separator + "X.class"); 918 if (!actualOutput.equals(expectedOutput)) { 919 printIt(actualOutput); 920 assertEquals(expectedOutput,actualOutput); 921 } 922 } 923 test022_nestedLambdas()924 public void test022_nestedLambdas() throws Exception { 925 this.runConformTest( 926 new String[]{ 927 "X.java", 928 "import java.io.Serializable;\n"+ 929 "interface Foo extends Serializable {int m();}\n"+ 930 "public class X {\n"+ 931 " public static void main(String argv[]) throws Exception {\n"+ 932 " Foo f = () -> { return ((Foo)()->33).m();};\n"+ 933 " System.out.println(f.m());\n"+ 934 " util.Helper.write(f);\n"+ 935 " f = (Foo)util.Helper.read();\n"+ 936 " System.out.println(f.m());\n"+ 937 " }\n"+ 938 "}", 939 "Helper.java",HELPER_CLASS, 940 }, 941 "33\n33", 942 null, 943 true, 944 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 945 String expectedOutput = 946 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 947 " Method arguments:\n"+ 948 " ()I\n"+ 949 " invokestatic X.lambda$0:()I\n"+ 950 " ()I\n"+ 951 " 1\n"+ 952 "1: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 953 " Method arguments:\n"+ 954 " ()I\n"+ 955 " invokestatic X.lambda$1:()I\n"+ 956 " ()I\n"+ 957 " 1\n"; 958 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 959 checkExpected(expectedOutput,data); 960 } 961 test023_lambdasInOtherPlaces_Field()962 public void test023_lambdasInOtherPlaces_Field() throws Exception { 963 this.runConformTest( 964 new String[]{ 965 "X.java", 966 "import java.io.Serializable;\n"+ 967 "interface Foo extends Serializable {int m();}\n"+ 968 "public class X {\n"+ 969 " Foo f = () -> 99;\n" + 970 " public static void main(String argv[]) throws Exception {\n"+ 971 " new X().run();\n"+ 972 " }\n"+ 973 " public void run() {\n"+ 974 " System.out.println(f.m());\n"+ 975 " util.Helper.write(f);\n"+ 976 " f = (Foo)util.Helper.read();\n"+ 977 " System.out.println(f.m());\n"+ 978 " }\n"+ 979 "}", 980 "Helper.java",HELPER_CLASS, 981 }, 982 "99\n99", 983 null, 984 true, 985 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 986 String expectedOutput = 987 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 988 " Method arguments:\n"+ 989 " ()I\n"+ 990 " invokestatic X.lambda$0:()I\n"+ 991 " ()I\n"+ 992 " 1\n"; 993 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 994 checkExpected(expectedOutput,data); 995 } 996 test024_lambdasInOtherPlaces_MethodParameter()997 public void test024_lambdasInOtherPlaces_MethodParameter() throws Exception { 998 this.runConformTest( 999 new String[]{ 1000 "X.java", 1001 "import java.io.Serializable;\n"+ 1002 "interface Foo extends Serializable {int m();}\n"+ 1003 "public class X {\n"+ 1004 " public static void main(String argv[]) throws Exception {\n"+ 1005 " new X().run(()->33);\n"+ 1006 " }\n"+ 1007 " public void run(Foo f) {\n"+ 1008 " System.out.println(f.m());\n"+ 1009 " util.Helper.write(f);\n"+ 1010 " f = (Foo)util.Helper.read();\n"+ 1011 " System.out.println(f.m());\n"+ 1012 " }\n"+ 1013 "}", 1014 "Helper.java",HELPER_CLASS, 1015 }, 1016 "33\n33", 1017 null, 1018 true, 1019 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1020 String expectedOutput = 1021 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 1022 " Method arguments:\n"+ 1023 " ()I\n"+ 1024 " invokestatic X.lambda$0:()I\n"+ 1025 " ()I\n"+ 1026 " 1\n"; 1027 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 1028 checkExpected(expectedOutput,data); 1029 } 1030 test025_lambdasWithGenericInferencing()1031 public void test025_lambdasWithGenericInferencing() throws Exception { 1032 this.runConformTest( 1033 new String[]{ 1034 "X.java", 1035 "import java.io.Serializable;\n"+ 1036 "import java.util.function.*;\n"+ 1037 "public class X {\n"+ 1038 " public static void main(String argv[]) throws Exception {\n"+ 1039 " new X().run();\n"+ 1040 " }\n"+ 1041 " public void run() {\n"+ 1042 " IntFunction<Integer> times3 = (IntFunction<Integer> & Serializable) (triple) -> 3 * triple;\n"+ 1043 " System.out.println(times3.apply(4));\n"+ 1044 " util.Helper.write(times3);\n"+ 1045 " times3 = (IntFunction<Integer>)util.Helper.read();\n"+ 1046 " System.out.println(times3.apply(4));\n"+ 1047 " }\n"+ 1048 "}", 1049 "Helper.java",HELPER_CLASS, 1050 }, 1051 "12\n12", 1052 null, 1053 true, 1054 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1055 String expectedOutput = 1056 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 1057 " Method arguments:\n"+ 1058 " (I)Ljava/lang/Object;\n"+ 1059 " invokestatic X.lambda$0:(I)Ljava/lang/Integer;\n"+ 1060 " (I)Ljava/lang/Integer;\n"+ 1061 " 1\n"; 1062 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 1063 checkExpected(expectedOutput,data); 1064 } test026_lambdasInOtherPlaces_Clinit()1065 public void test026_lambdasInOtherPlaces_Clinit() throws Exception { 1066 this.runConformTest( 1067 new String[]{ 1068 "X.java", 1069 "import java.io.Serializable;\n"+ 1070 "interface Foo extends Serializable {int m();}\n"+ 1071 "public class X {\n"+ 1072 " static {\n"+ 1073 " Foo f = () -> 99;\n" + 1074 " }\n"+ 1075 " public static void main(String argv[]) throws Exception {\n"+ 1076 " new X().run();\n"+ 1077 " }\n"+ 1078 " public void run() {\n"+ 1079 " Foo f = ()->99;\n"+ 1080 " System.out.println(f.m());\n"+ 1081 " util.Helper.write(f);\n"+ 1082 " f = (Foo)util.Helper.read();\n"+ 1083 " System.out.println(f.m());\n"+ 1084 " }\n"+ 1085 "}", 1086 "Helper.java",HELPER_CLASS, 1087 }, 1088 "99\n99", 1089 null, 1090 true, 1091 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1092 String expectedOutput = 1093 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 1094 " Method arguments:\n"+ 1095 " ()I\n"+ 1096 " invokestatic X.lambda$0:()I\n"+ 1097 " ()I\n"+ 1098 " 1\n"+ 1099 "1: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 1100 " Method arguments:\n"+ 1101 " ()I\n"+ 1102 " invokestatic X.lambda$1:()I\n"+ 1103 " ()I\n"+ 1104 " 1\n"; 1105 String data = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "X.class"); 1106 checkExpected(expectedOutput,data); 1107 } 1108 1109 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=449467 - [1.8][compiler] Invalid lambda deserialization with anonymous class test449467()1110 public void test449467() throws Exception { 1111 this.runConformTest( 1112 new String[]{ 1113 "TestClass.java", 1114 "import java.io.ByteArrayInputStream;\n"+ 1115 "import java.io.ByteArrayOutputStream;\n"+ 1116 "import java.io.ObjectInputStream;\n"+ 1117 "import java.io.ObjectOutputStream;\n"+ 1118 "import java.io.Serializable;\n"+ 1119 "\n"+ 1120 "public class TestClass implements Serializable {\n"+ 1121 " String msg = \"HEY!\";\n"+ 1122 " OtherClass other;\n"+ 1123 "\n"+ 1124 " public TestClass(StringBuilder sb) {\n"+ 1125 " other = new OtherClass() {\n"+ 1126 " {\n"+ 1127 " other2 = new OtherClass2((Runnable & Serializable) () -> {\n"+ 1128 " sb.length();\n"+ 1129 " say();\n"+ 1130 " });\n"+ 1131 " }\n"+ 1132 " };\n"+ 1133 " }\n"+ 1134 "\n"+ 1135 " public void say() {\n"+ 1136 " System.out.println(msg);\n"+ 1137 " }\n"+ 1138 "\n"+ 1139 " public static void main(String[] args) throws Exception {\n"+ 1140 " ByteArrayOutputStream buffer = new ByteArrayOutputStream();\n"+ 1141 " try (ObjectOutputStream out = new ObjectOutputStream(buffer)) {\n"+ 1142 " out.writeObject(new TestClass(new StringBuilder()));\n"+ 1143 " }\n"+ 1144 " try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()))) {\n"+ 1145 " TestClass s = (TestClass) in.readObject();\n"+ 1146 " s.say();\n"+ 1147 " }\n"+ 1148 " }\n"+ 1149 "}\n"+ 1150 "\n"+ 1151 "class OtherClass implements Serializable {\n"+ 1152 " OtherClass2 other2;\n"+ 1153 "}\n"+ 1154 "\n"+ 1155 "class OtherClass2 implements Serializable {\n"+ 1156 " Runnable runnable;\n"+ 1157 "\n"+ 1158 " public OtherClass2(Runnable runnable) {\n"+ 1159 " this.runnable = runnable;\n"+ 1160 " }\n"+ 1161 "}\n" 1162 }, 1163 "HEY!", 1164 null, 1165 true, 1166 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1167 } 1168 test449467_2()1169 public void test449467_2() throws Exception { 1170 this.runConformTest( 1171 new String[]{ 1172 "com/foo/TestClass.java", 1173 "package com.foo;\n"+ 1174 "import java.io.ByteArrayInputStream;\n"+ 1175 "import java.io.ByteArrayOutputStream;\n"+ 1176 "import java.io.ObjectInputStream;\n"+ 1177 "import java.io.ObjectOutputStream;\n"+ 1178 "import java.io.Serializable;\n"+ 1179 "public class TestClass implements Serializable {\n"+ 1180 " String msg = \"HEY!\";\n"+ 1181 " OtherClass other;\n"+ 1182 "\n"+ 1183 " public TestClass(StringBuilder sb) {\n"+ 1184 " other = new OtherClass() {\n"+ 1185 " {\n"+ 1186 " other2 = new OtherClass2((Runnable & Serializable) () -> {\n"+ 1187 " sb.length();\n"+ 1188 " say();\n"+ 1189 " });\n"+ 1190 " }\n"+ 1191 " };\n"+ 1192 " }\n"+ 1193 "\n"+ 1194 " public void say() {\n"+ 1195 " System.out.println(msg);\n"+ 1196 " }\n"+ 1197 "\n"+ 1198 " public static void main(String[] args) throws Exception {\n"+ 1199 " ByteArrayOutputStream buffer = new ByteArrayOutputStream();\n"+ 1200 " try (ObjectOutputStream out = new ObjectOutputStream(buffer)) {\n"+ 1201 " out.writeObject(new TestClass(new StringBuilder()));\n"+ 1202 " }\n"+ 1203 " try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()))) {\n"+ 1204 " TestClass s = (TestClass) in.readObject();\n"+ 1205 " s.say();\n"+ 1206 " }\n"+ 1207 " }\n"+ 1208 "}\n"+ 1209 "\n"+ 1210 "class OtherClass implements Serializable {\n"+ 1211 " OtherClass2 other2;\n"+ 1212 "}\n"+ 1213 "\n"+ 1214 "class OtherClass2 implements Serializable {\n"+ 1215 " Runnable runnable;\n"+ 1216 "\n"+ 1217 " public OtherClass2(Runnable runnable) {\n"+ 1218 " this.runnable = runnable;\n"+ 1219 " }\n"+ 1220 "}\n" 1221 }, 1222 "HEY!", 1223 null, 1224 true, 1225 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1226 } 1227 1228 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428552, [1.8][compiler][codegen] Serialization does not work for method references test428552()1229 public void test428552() throws Exception { 1230 this.runConformTest( 1231 new String[]{ 1232 "X.java", 1233 "import java.io.*;\n" + 1234 "public class X {\n" + 1235 " interface Example extends Serializable {\n" + 1236 " String convert(X o);\n" + 1237 " }\n" + 1238 " public static void main(String[] args) throws IOException {\n" + 1239 " Example e=X::toString;\n" + 1240 " util.Helper.write(e);\n"+ 1241 " e = (Example)util.Helper.read();\n"+ 1242 " System.out.println(e.convert(new X()));\n"+ 1243 " }\n" + 1244 " public String toString() {\n" + 1245 " return \"XItIs\";\n" + 1246 " }\n" + 1247 "}\n", 1248 "Helper.java",HELPER_CLASS, 1249 }, 1250 "XItIs", 1251 null, 1252 true, 1253 new String [] { "-Ddummy" }); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1254 } 1255 1256 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=428642 test428642()1257 public void test428642() throws Exception { 1258 this.runConformTest( 1259 new String[]{ 1260 "QuickSerializedLambdaTest.java", 1261 "import java.io.*;\n"+ 1262 "import java.util.function.IntConsumer;\n"+ 1263 "\n"+ 1264 "public class QuickSerializedLambdaTest {\n"+ 1265 " interface X extends IntConsumer,Serializable{}\n"+ 1266 " public static void main(String[] args) throws IOException, ClassNotFoundException {\n"+ 1267 " X x2 = System::exit; // method reference\n"+ 1268 " ByteArrayOutputStream debug=new ByteArrayOutputStream();\n"+ 1269 " try(ObjectOutputStream oo=new ObjectOutputStream(debug))\n"+ 1270 " {\n"+ 1271 " oo.writeObject(x2);\n"+ 1272 " }\n"+ 1273 " try(ObjectInputStream oi=new ObjectInputStream(new ByteArrayInputStream(debug.toByteArray())))\n"+ 1274 " {\n"+ 1275 " X x=(X)oi.readObject();\n"+ 1276 " x.accept(0);// shall exit\n"+ 1277 " }\n"+ 1278 " throw new AssertionError(\"should not reach this point\");\n"+ 1279 " }\n"+ 1280 "}\n", 1281 "Helper.java", 1282 "public class Helper {\n"+ 1283 " public static String tostring(java.lang.invoke.SerializedLambda sl) {\n"+ 1284 " return sl.toString();\n"+ 1285 " }\n"+ 1286 "}" 1287 }, 1288 "", 1289 null,true, 1290 new String[]{"-Ddummy"}); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1291 } 1292 test428642_2()1293 public void test428642_2() throws Exception { 1294 this.runConformTest( 1295 new String[]{ 1296 "Helper.java", 1297 "public class Helper {\n"+ 1298 " public static String tostring(java.lang.invoke.SerializedLambda sl) {\n"+ 1299 " return sl.toString();\n"+ 1300 " }\n"+ 1301 " public static void main(String[]argv) throws Exception {\n"+ 1302 " foo.QuickSerializedLambdaTest.main(argv);\n"+ 1303 " }\n"+ 1304 "}", 1305 "QuickSerializedLambdaTest.java", 1306 "package foo;\n"+ 1307 "import java.io.*;\n"+ 1308 "import java.util.function.IntConsumer;\n"+ 1309 "\n"+ 1310 "public class QuickSerializedLambdaTest {\n"+ 1311 " interface X extends IntConsumer,Serializable{}\n"+ 1312 " public static void main(String[] args) throws IOException, ClassNotFoundException {\n"+ 1313 " X x1 = i -> System.out.println(i);// lambda expression\n"+ 1314 " X x2 = System::exit; // method reference\n"+ 1315 " ByteArrayOutputStream debug=new ByteArrayOutputStream();\n"+ 1316 " try(ObjectOutputStream oo=new ObjectOutputStream(debug))\n"+ 1317 " {\n"+ 1318 " oo.writeObject(x1);\n"+ 1319 " oo.writeObject(x2);\n"+ 1320 " }\n"+ 1321 " try(ObjectInputStream oi=new ObjectInputStream(new ByteArrayInputStream(debug.toByteArray())))\n"+ 1322 " {\n"+ 1323 " X x=(X)oi.readObject();\n"+ 1324 " x.accept(42);// shall print \"42\"\n"+ 1325 " x=(X)oi.readObject();\n"+ 1326 " x.accept(0);// shall exit\n"+ 1327 " }\n"+ 1328 " throw new AssertionError(\"should not reach this point\");\n"+ 1329 " }\n"+ 1330 "}\n" 1331 }, 1332 "42", 1333 null,true, 1334 new String[]{"-Ddummy"}); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1335 } 1336 1337 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=429112, [1.8][compiler] Exception when compiling Serializable array constructor reference test429112()1338 public void test429112() throws Exception { 1339 this.runConformTest( 1340 new String[]{ 1341 "X.java", 1342 "import java.io.*;\n" + 1343 "import java.util.function.IntFunction;\n" + 1344 "public class X {\n" + 1345 " interface IF extends IntFunction<Object>, Serializable {}\n" + 1346 " public static void main(String[] args) throws IOException, ClassNotFoundException {\n" + 1347 " IF factory=String[]::new;\n" + 1348 " Object o = factory.apply(1234);\n" + 1349 " ByteArrayOutputStream debug=new ByteArrayOutputStream();\n"+ 1350 " try(ObjectOutputStream oo=new ObjectOutputStream(debug))\n"+ 1351 " {\n"+ 1352 " oo.writeObject(factory);\n"+ 1353 " }\n"+ 1354 " try(ObjectInputStream oi=new ObjectInputStream(new ByteArrayInputStream(debug.toByteArray())))\n"+ 1355 " {\n"+ 1356 " IF x = (IF)oi.readObject();\n"+ 1357 " Object p = x.apply(1234);\n"+ 1358 " System.out.println(p.getClass());\n" + 1359 " String [] sa = (String []) p;\n" + 1360 " System.out.println(sa.length);\n" + 1361 " }\n"+ 1362 " }\n"+ 1363 "}\n", 1364 }, 1365 "class [Ljava.lang.String;\n" + 1366 "1234", 1367 null,true, 1368 new String[]{"-Ddummy"}); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1369 } 1370 1371 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=439889 - [1.8][compiler] [lambda] Deserializing lambda fails with IllegalArgumentException: "Invalid lambda deserialization" test439889()1372 public void test439889() throws Exception { 1373 this.runConformTest( 1374 new String[]{ 1375 "SerializationTest.java", 1376 "import java.io.*;\n"+ 1377 "\n"+ 1378 "public class SerializationTest implements Serializable {\n"+ 1379 " interface SerializableRunnable extends Runnable, Serializable {\n"+ 1380 " }\n"+ 1381 "\n"+ 1382 " SerializableRunnable runnable;\n"+ 1383 "\n"+ 1384 " public SerializationTest() {\n"+ 1385 " final SerializationTest self = this;\n"+ 1386 " // runnable = () -> self.doSomething();\n"+ 1387 " runnable = () -> this.doSomething();\n"+ // results in this method handle: #166 invokespecial SerializationTest.lambda$0:()V 1388 " }\n"+ 1389 "\n"+ 1390 " public void doSomething() {\n"+ 1391 " System.out.println(\"Hello,world!\");\n"+ 1392 " }\n"+ 1393 "\n"+ 1394 " public static void main(String[] args) throws Exception {\n"+ 1395 " final ByteArrayOutputStream buffer = new ByteArrayOutputStream();\n"+ 1396 " try (ObjectOutputStream out = new ObjectOutputStream(buffer) ) {\n"+ 1397 " out.writeObject(new SerializationTest());\n"+ 1398 " }\n"+ 1399 " try (ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream(buffer.toByteArray()))) {\n"+ 1400 " final SerializationTest s = (SerializationTest) in.readObject();\n"+ 1401 " s.doSomething();\n"+ 1402 " }\n"+ 1403 " }\n"+ 1404 "}\n" 1405 }, 1406 "Hello,world!", 1407 null,true, 1408 new String[]{"-Ddummy"}); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1409 } 1410 test439889_2()1411 public void test439889_2() throws Exception { 1412 this.runConformTest( 1413 new String[]{ 1414 "SerializationTest.java", 1415 "import java.io.*;\n"+ 1416 "\n"+ 1417 "public class SerializationTest implements Serializable {\n"+ 1418 " interface SerializableRunnable extends Runnable, Serializable {\n"+ 1419 " }\n"+ 1420 "\n"+ 1421 " SerializableRunnable runnable;\n"+ 1422 "\n"+ 1423 " public SerializationTest() {\n"+ 1424 " final SerializationTest self = this;\n"+ 1425 " runnable = () -> self.doSomething();\n"+ // results in this method handle: #168 invokestatic SerializationTest.lambda$0:(LSerializationTest;)V 1426 " // runnable = () -> this.doSomething();\n"+ 1427 " }\n"+ 1428 "\n"+ 1429 " public void doSomething() {\n"+ 1430 " System.out.println(\"Hello,world!\");\n"+ 1431 " }\n"+ 1432 "\n"+ 1433 " public static void main(String[] args) throws Exception {\n"+ 1434 " final ByteArrayOutputStream buffer = new ByteArrayOutputStream();\n"+ 1435 " try (ObjectOutputStream out = new ObjectOutputStream(buffer) ) {\n"+ 1436 " out.writeObject(new SerializationTest());\n"+ 1437 " }\n"+ 1438 " try (ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream(buffer.toByteArray()))) {\n"+ 1439 " final SerializationTest s = (SerializationTest) in.readObject();\n"+ 1440 " s.doSomething();\n"+ 1441 " }\n"+ 1442 " }\n"+ 1443 "}\n" 1444 }, 1445 "Hello,world!", 1446 null,true, 1447 new String[]{"-Ddummy"}); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1448 } 1449 testNestedLambdas_442416()1450 public void testNestedLambdas_442416() throws Exception { 1451 this.runConformTest( 1452 new String[]{ 1453 "Foo.java", 1454 "import java.io.*;\n"+ 1455 "public class Foo {\n"+ 1456 " static byte[] toSer(Object o) {\n"+ 1457 " try {\n"+ 1458 " final ByteArrayOutputStream buffer = new ByteArrayOutputStream();\n"+ 1459 " try (ObjectOutputStream out = new ObjectOutputStream(buffer) ) {\n"+ 1460 " out.writeObject(o);\n"+ 1461 " }\n"+ 1462 " return buffer.toByteArray();\n"+ 1463 " } catch (Exception e) {e.printStackTrace();return null;}\n"+ 1464 " }\n"+ 1465 " static Object fromSer(byte[] bs) {\n"+ 1466 " try {\n"+ 1467 " try (ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream(bs))) {\n"+ 1468 " final Object s = in.readObject();\n"+ 1469 " return s;\n"+ 1470 " }\n"+ 1471 " } catch (Exception e) {e.printStackTrace();return null;}\n"+ 1472 " }\n"+ 1473 " public static void main(String[] args) throws Exception {\n"+ 1474 " Runnable nested1,nested2;\n"+ 1475 " Runnable lambda0 = (java.io.Serializable & Runnable) () -> {\n"+ 1476 " Runnable lambda1 = (java.io.Serializable & Runnable) () -> {\n"+ 1477 " Runnable lambda2 = (java.io.Serializable & Runnable) () -> {\n"+ 1478 " System.out.println(\"Hello,world!\");\n"+ 1479 " };\n"+ 1480 " byte[] bs = toSer(lambda2);\n"+ 1481 " Runnable r = (Runnable)fromSer(bs);\n"+ 1482 " r.run();\n"+ 1483 " };\n"+ 1484 " byte[] bs = toSer(lambda1);\n"+ 1485 " Runnable r = (Runnable)fromSer(bs);\n"+ 1486 " r.run();\n"+ 1487 " };\n"+ 1488 " byte[] bs = toSer(lambda0);\n"+ 1489 " Runnable r = (Runnable)fromSer(bs);\n"+ 1490 " r.run();\n"+ 1491 " }\n"+ 1492 "}\n", 1493 }, 1494 "Hello,world!", 1495 null,true, 1496 new String[]{"-Ddummy"}); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1497 } 1498 testBindingThis_442418()1499 public void testBindingThis_442418() throws Exception { 1500 this.runConformTest( 1501 new String[]{ 1502 "Foo.java", 1503 "import java.io.*;\n"+ 1504 "public class Foo implements Serializable {\n"+ 1505 " static byte[] toSer(Object o) {\n"+ 1506 " try {\n"+ 1507 " final ByteArrayOutputStream buffer = new ByteArrayOutputStream();\n"+ 1508 " try (ObjectOutputStream out = new ObjectOutputStream(buffer) ) {\n"+ 1509 " out.writeObject(o);\n"+ 1510 " }\n"+ 1511 " return buffer.toByteArray();\n"+ 1512 " } catch (Exception e) {e.printStackTrace();return null;}\n"+ 1513 " }\n"+ 1514 " static Object fromSer(byte[] bs) {\n"+ 1515 " try {\n"+ 1516 " try (ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream(bs))) {\n"+ 1517 " final Object s = in.readObject();\n"+ 1518 " return s;\n"+ 1519 " }\n"+ 1520 " } catch (Exception e) {e.printStackTrace();return null;}\n"+ 1521 " }\n"+ 1522 " void m(int i) {\n"+ 1523 " System.out.println(i);\n"+ 1524 " }\n"+ 1525 " void n(int i) {\n"+ 1526 " Runnable lambda = (java.io.Serializable & Runnable) () -> { this.m(i); };\n"+ 1527 " byte[] bs = toSer(lambda);\n"+ 1528 " Runnable r = (Runnable)fromSer(bs);\n"+ 1529 " r.run();\n"+ 1530 " }\n"+ 1531 " public static void main(String[] args) throws Exception {\n"+ 1532 " new Foo().n(42);\n"+ 1533 " }\n"+ 1534 "}\n", 1535 }, 1536 "42", 1537 null,true, 1538 new String[]{"-Ddummy"}); // Not sure, unless we force the VM to not be reused by passing dummy vm argument, the generated program aborts midway through its execution. 1539 } 1540 testbug479119()1541 public void testbug479119() { 1542 this.runConformTest( 1543 new String[]{ 1544 "Testbed.java", 1545 "import java.io.ObjectStreamClass;\n" + 1546 "import java.io.Serializable;\n" + 1547 "import java.lang.invoke.SerializedLambda;\n" + 1548 "import java.lang.reflect.Method;\n" + 1549 "import java.util.function.IntFunction;\n" + 1550 "import java.util.stream.Stream;\n" + 1551 "public class Testbed {\n" + 1552 " public static void main(String[] args) {\n" + 1553 " System.out.println(getMethod(Testbed::foo).equals(getMethod(Testbed::foo)));\n" + 1554 " }\n" + 1555 " private static void foo() { }\n" + 1556 " static interface MethodRef extends Runnable, Serializable { }\n" + 1557 " private static Method getMethod(MethodRef methodRef) {\n" + 1558 " try {\n" + 1559 " final Method invokeWriteReplaceMethod = ObjectStreamClass.class.getDeclaredMethod(\"invokeWriteReplace\", Object.class);\n" + 1560 " invokeWriteReplaceMethod.setAccessible(true);\n" + 1561 " final SerializedLambda l = (SerializedLambda)invokeWriteReplaceMethod.invoke(\n" + 1562 " ObjectStreamClass.lookupAny(methodRef.getClass()),\n" + 1563 " methodRef\n" + 1564 " );\n" + 1565 " System.out.println(\"Looking for \" + l.getImplClass() + \".\" + l.getImplMethodName());\n" + 1566 " final Method[] methods = Stream.of(Class.forName(l.getImplClass()).getDeclaredMethods()).\n" + 1567 " filter(m -> m.getName().equals(l.getImplMethodName())).\n" + 1568 " toArray(Method[]::new);\n" + 1569 " if(methods.length != 1) throw new AssertionError(\"TODO: check signature\");\n" + 1570 " return methods[0];\n" + 1571 " } catch(Exception e) {\n" + 1572 " throw new RuntimeException(e);\n" + 1573 " }\n" + 1574 " }\n" + 1575 "}\n" 1576 }, 1577 "Looking for Testbed.foo\n" + 1578 "Looking for Testbed.foo\n" + 1579 "true", 1580 null,true, 1581 (isJRE9Plus 1582 ? new String[] { "--add-opens", "java.base/java.io=ALL-UNNAMED" } 1583 : new String [] { "-Ddummy" }) 1584 ); 1585 1586 1587 String bootstrapEntries = printBootstrapMethodsAttribute(OUTPUT_DIR + File.separator + "Testbed.class"); 1588 String expectedOutput = 1589 "0: invokestatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;\n"+ 1590 " Method arguments:\n"+ 1591 " ()V\n"+ 1592 " invokestatic Testbed.foo:()V\n"+ 1593 " ()V\n"+ 1594 " 1\n"+ 1595 "1: invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;\n"+ 1596 " Method arguments:\n"+ 1597 " (Ljava/lang/Object;)Z\n"+ 1598 " invokestatic Testbed.lambda$2:(Ljava/lang/invoke/SerializedLambda;Ljava/lang/reflect/Method;)Z\n"+ 1599 " (Ljava/lang/reflect/Method;)Z\n"+ 1600 "2: invokestatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;\n"+ 1601 " Method arguments:\n"+ 1602 " (I)Ljava/lang/Object;\n"+ 1603 " invokestatic Testbed.lambda$3:(I)[Ljava/lang/reflect/Method;\n"+ 1604 " (I)[Ljava/lang/reflect/Method;\n"; 1605 1606 checkExpected(expectedOutput, bootstrapEntries); 1607 } 1608 testbug479119a()1609 public void testbug479119a() { 1610 this.runConformTest( 1611 new String[]{ 1612 "Testbed.java", 1613 "import java.io.ObjectStreamClass;\n" + 1614 "import java.io.Serializable;\n" + 1615 "import java.lang.invoke.SerializedLambda;\n" + 1616 "import java.lang.reflect.Constructor;\n" + 1617 "import java.lang.reflect.Executable;\n" + 1618 "import java.lang.reflect.Method;\n" + 1619 "import java.util.function.IntFunction;\n" + 1620 "import java.util.stream.Stream;\n" + 1621 "public class Testbed {\n" + 1622 " public static void main(String[] args) {\n" + 1623 " System.out.println(getMethod(Testbed::foo).equals(getMethod(Testbed::foo)));\n" + 1624 " System.out.println(getMethod(new Foo()::method).equals(getMethod(new Bar()::method)));\n" + 1625 " System.out.println(getMethod(MethodRefImpl::new).equals(getMethod(MethodRefImpl::new)));\n" + 1626 " }\n" + 1627 " static class MethodRefImpl implements MethodRef {\n" + 1628 " @Override\n" + 1629 " public void run() {}\n" + 1630 " }\n" + 1631 " public static class Base {\n" + 1632 " public void method () {}\n" + 1633 " }\n" + 1634 " public static class Foo extends Base {}\n" + 1635 " public static class Bar extends Base {}\n" + 1636 " private static void foo() { }\n" + 1637 " static interface MethodRef extends Runnable, Serializable { }\n" + 1638 " private static Executable getMethod(MethodRef methodRef) {\n" + 1639 " try {\n" + 1640 " final Method invokeWriteReplaceMethod = ObjectStreamClass.class.getDeclaredMethod(\"invokeWriteReplace\", Object.class);\n" + 1641 " invokeWriteReplaceMethod.setAccessible(true);\n" + 1642 " final SerializedLambda l = (SerializedLambda)invokeWriteReplaceMethod.invoke(\n" + 1643 " ObjectStreamClass.lookupAny(methodRef.getClass()),\n" + 1644 " methodRef\n" + 1645 " );\n" + 1646 " System.out.println(\"Looking for \" + l.getImplClass() + \".\" + l.getImplMethodName());\n" + 1647 " boolean isConstructor = l.getImplMethodName().indexOf(\"<init>\") >= 0;\n" + 1648 " final Executable[] methods = Stream.of(isConstructor ? Class.forName(l.getImplClass()).getDeclaredConstructors() : Class.forName(l.getImplClass()).getDeclaredMethods()).\n" + 1649 " filter(m -> m.getName().equals(isConstructor ? l.getImplClass() : l.getImplMethodName())).\n" + 1650 " toArray(isConstructor ? Constructor[]::new : Method[]::new);\n" + 1651 " if(methods.length != 1) throw new AssertionError(\"TODO: check signature\");\n" + 1652 " return methods[0];\n" + 1653 " } catch(Exception e) {\n" + 1654 " throw new RuntimeException(e);\n" + 1655 " }\n" + 1656 " }\n" + 1657 "}\n" 1658 }, 1659 "Looking for Testbed.foo\n" + 1660 "Looking for Testbed.foo\n" + 1661 "true\n" + 1662 "Looking for Testbed$Base.method\n" + 1663 "Looking for Testbed$Base.method\n" + 1664 "true\n" + 1665 "Looking for Testbed$MethodRefImpl.<init>\n" + 1666 "Looking for Testbed$MethodRefImpl.<init>\n" + 1667 "true", 1668 null,true, 1669 (isJRE9Plus 1670 ? new String[] { "--add-opens", "java.base/java.io=ALL-UNNAMED" } 1671 : new String [] { "-Ddummy" }) 1672 ); 1673 } 1674 1675 // Serializable reference expressions that share the same name testbug479119b()1676 public void testbug479119b() { 1677 this.runConformTest( 1678 new String[]{ 1679 "X.java", 1680 "import java.io.ByteArrayInputStream;\n" + 1681 "import java.io.ByteArrayOutputStream;\n" + 1682 "import java.io.IOException;\n" + 1683 "import java.io.ObjectInputStream;\n" + 1684 "import java.io.ObjectOutputStream;\n" + 1685 "import java.io.Serializable;\n" + 1686 "public class X {\n" + 1687 " public static interface Consumer<T> extends Serializable {\n" + 1688 " void accept(T t);\n" + 1689 " }\n" + 1690 " public static class Foo {\n" + 1691 " public void method () {\n" + 1692 " System.out.println(\"Foo\");\n" + 1693 " }\n" + 1694 " }\n" + 1695 " public static class Bar {\n" + 1696 " public void method () {\n" + 1697 " System.out.println(\"Bar\");\n" + 1698 " }\n" + 1699 " }\n" + 1700 " public static void main (String[] args) throws IOException, ClassNotFoundException {\n" + 1701 " Consumer<Foo> foo = Foo::method;\n" + 1702 " Consumer<Bar> bar = Bar::method;\n" + 1703 " Consumer<Foo> baz = (b) -> {b.method();};\n" + 1704 " ByteArrayOutputStream debug=new ByteArrayOutputStream();\n" + 1705 " try(ObjectOutputStream oo=new ObjectOutputStream(debug)) {\n" + 1706 " oo.writeObject(bar);\n" + 1707 " }\n" + 1708 " try(ObjectInputStream oi=new ObjectInputStream(new ByteArrayInputStream(debug.toByteArray()))) {\n" + 1709 " Consumer<Bar> x = (Consumer)oi.readObject();\n" + 1710 " x.accept(new Bar());\n" + 1711 " }\n" + 1712 " debug.reset();\n" + 1713 " try(ObjectOutputStream oo=new ObjectOutputStream(debug)) {\n" + 1714 " oo.writeObject(foo);\n" + 1715 " }\n" + 1716 " try(ObjectInputStream oi=new ObjectInputStream(new ByteArrayInputStream(debug.toByteArray()))) {\n" + 1717 " Consumer<Foo> x = (Consumer)oi.readObject();\n" + 1718 " x.accept(new Foo());\n" + 1719 " }\n" + 1720 " }\n" + 1721 "}\n" 1722 }, 1723 "Bar\n" + 1724 "Foo", 1725 null,true, 1726 new String[]{"-Ddummy"}); 1727 } testbug479119_comment20()1728 public void testbug479119_comment20() { 1729 this.runConformTest( 1730 new String[]{ 1731 "Testbed.java", 1732 "import java.io.ByteArrayInputStream;\n" + 1733 "import java.io.ByteArrayOutputStream;\n" + 1734 "import java.io.IOException;\n" + 1735 "import java.io.ObjectInputStream;\n" + 1736 "import java.io.ObjectOutputStream;\n" + 1737 "import java.io.Serializable;\n" + 1738 "interface FI extends Serializable{\n" + 1739 " void run(Testbed args);\n" + 1740 "}\n" + 1741 "interface IF extends Serializable{\n" + 1742 " void run();\n" + 1743 "}\n" + 1744 "public class Testbed implements Serializable{\n" + 1745 " String f;\n" + 1746 " Testbed(String str) {\n" + 1747 " f = str;\n" + 1748 " }\n" + 1749 " void test() throws IOException, ClassNotFoundException {\n" + 1750 " accept(Testbed::foo);\n" + 1751 " accept(this::foo); \n" + 1752 " }\n" + 1753 " void foo() {\n" + 1754 " System.out.println(this.f);\n" + 1755 " }\n" + 1756 " void accept(FI fi) {\n" + 1757 " fi.run(this);\n" + 1758 " }\n" + 1759 " void accept(IF i) {\n" + 1760 " i.run();\n" + 1761 " }\n" + 1762 " public static void main(String[] args) throws ClassNotFoundException, IOException {\n" + 1763 " Testbed t = new Testbed(\"IF\");\n" + 1764 " Testbed t2 = new Testbed(\"FI\");\n" + 1765 " IF i = t::foo;\n" + 1766 " FI f = Testbed::foo;\n" + 1767 " ByteArrayOutputStream debug=new ByteArrayOutputStream();\n" + 1768 " try(ObjectOutputStream oo=new ObjectOutputStream(debug))\n" + 1769 " {\n" + 1770 " oo.writeObject(i);\n" + 1771 " }\n" + 1772 " try(ObjectInputStream oi=new ObjectInputStream(new ByteArrayInputStream(debug.toByteArray())))\n" + 1773 " {\n" + 1774 " IF x = (IF)oi.readObject();\n" + 1775 " t.accept(x);\n" + 1776 " }\n" + 1777 " debug=new ByteArrayOutputStream();\n" + 1778 " try(ObjectOutputStream oo=new ObjectOutputStream(debug))\n" + 1779 " {\n" + 1780 " oo.writeObject(f);\n" + 1781 " }\n" + 1782 " try(ObjectInputStream oi=new ObjectInputStream(new ByteArrayInputStream(debug.toByteArray())))\n" + 1783 " {\n" + 1784 " FI x = (FI)oi.readObject();\n" + 1785 " t2.accept(x);\n" + 1786 " }\n" + 1787 " }\n" + 1788 "}" 1789 }, 1790 "IF\n" + 1791 "FI", 1792 null,true, 1793 new String[]{"-Ddummy"}); 1794 } testbug485333()1795 public void testbug485333() { 1796 this.runConformTest( 1797 new String[]{ 1798 "Test.java", 1799 "import java.io.ByteArrayInputStream;\n" + 1800 "import java.io.ByteArrayOutputStream;\n" + 1801 "import java.io.ObjectInputStream;\n" + 1802 "import java.io.ObjectOutputStream;\n" + 1803 "import java.io.Serializable;\n" + 1804 "interface Func<T> extends Serializable {\n" + 1805 " T get();\n" + 1806 "}\n" + 1807 "class Impl implements Serializable {\n" + 1808 " int val = 0;\n" + 1809 " public int next() {\n" + 1810 " val += 1;\n" + 1811 " return val;\n" + 1812 " }\n" + 1813 "}\n" + 1814 "public class Test {\n" + 1815 " final Impl impl = new Impl();\n" + 1816 " final Func<Integer> func = (Func<Integer> & Cloneable)impl::next;\n" + 1817 " public void test() throws Throwable {\n" + 1818 " byte[] bytes = write(func);//25\n" + 1819 " Func<Integer> func = read(bytes);\n" + 1820 " System.out.println(func.get());\n" + 1821 " }\n" + 1822 " public static void main(String[] args) throws Throwable {\n" + 1823 " new Test().test();\n" + 1824 "}\n" + 1825 " @SuppressWarnings(\"unchecked\")\n" + 1826 " private static Func<Integer> read(byte[] bytes) throws Exception {\n" + 1827 " ByteArrayInputStream bis = new ByteArrayInputStream(bytes);\n" + 1828 " try (ObjectInputStream ois = new ObjectInputStream(bis)) {\n" + 1829 " return (Func<Integer>) ois.readObject();\n" + 1830 " }\n" + 1831 " }\n" + 1832 " private static byte[] write(Func<Integer> func) throws Exception {\n" + 1833 " ByteArrayOutputStream bos = new ByteArrayOutputStream();\n" + 1834 " System.out.println(func.get());\n" + 1835 " try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {\n" + 1836 " oos.writeObject(func);//42\n" + 1837 " }\n" + 1838 " return bos.toByteArray();\n" + 1839 " }\n" + 1840 "}" 1841 }, 1842 "1\n" + 1843 "2", 1844 null,true, 1845 new String[]{"-Ddummy"}); 1846 } testbug494487()1847 public void testbug494487() { 1848 Map options = getCompilerOptions(); 1849 options.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE); 1850 this.runConformTest( 1851 new String[]{ 1852 "Test.java", 1853 "import java.io.IOException;\n" + 1854 "import java.io.Serializable;\n" + 1855 "public class Test {\n" + 1856 " class AnException extends Exception {\n" + 1857 " }\n" + 1858 " class Asd {\n" + 1859 " public Asd(String asd) { data = asd; }\n" + 1860 " private final String data;\n" + 1861 " @Override\n" + 1862 " public String toString() {\n" + 1863 " return data;\n" + 1864 " }\n" + 1865 " }\n" + 1866 " public interface Test1 extends Serializable {\n" + 1867 " void test() throws IOException;\n" + 1868 " }\n" + 1869 " public interface Test2 {\n" + 1870 " void test() throws AnException;\n" + 1871 " }\n" + 1872 " public void test1( Test1 test ) {\n" + 1873 " try {\n" + 1874 " test.test();\n" + 1875 " } catch( IOException e ) {\n" + 1876 " e.printStackTrace();\n" + 1877 " }\n" + 1878 " }\n" + 1879 " public void test2( Test2 test ) {\n" + 1880 " try {\n" + 1881 " test.test();\n" + 1882 " } catch( AnException e ) {\n" + 1883 " System.out.println( e );\n" + 1884 " }\n" + 1885 " }\n" + 1886 " public void lambdas() {\n" + 1887 " test1( () -> System.out.println( \"test a\" ) );\n" + 1888 " test1( () -> System.out.println( \"test b\" ) );\n" + 1889 " test2( () -> System.out.println( \"test c\" ) );\n" + 1890 " test2( () -> System.out.println( \"test d\" ) );\n" + 1891 " }\n" + 1892 " public void print( CharSequence a, String b, long c ) {\n" + 1893 " System.out.println( a );\n" + 1894 " System.out.println( b );\n" + 1895 " System.out.println( c );\n" + 1896 " }\n" + 1897 " public void filler() {\n" + 1898 " System.out.println( \"Now we need to get this class file closer to 3000 bytes boundary\" );\n" + 1899 " filler1();\n" + 1900 " filler2();\n" + 1901 " filler3();\n" + 1902 " filler4();\n" + 1903 " filler5();\n" + 1904 " filler6();\n" + 1905 " filler7();\n" + 1906 " filler8();\n" + 1907 " filler9();\n" + 1908 " filler10();\n" + 1909 " filler11();\n" + 1910 " filler12();\n" + 1911 " filler13();\n" + 1912 " filler14();\n" + 1913 " filler15();\n" + 1914 " filler16();\n" + 1915 " filler17();\n" + 1916 " filler18();\n" + 1917 " filler19();\n" + 1918 " filler20();\n" + 1919 " filler21();\n" + 1920 " filler22();\n" + 1921 " filler23();\n" + 1922 " filler24();\n" + 1923 " filler25();\n" + 1924 " filler26();\n" + 1925 " filler27();\n" + 1926 " filler28();\n" + 1927 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1928 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1929 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1930 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1931 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1932 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1933 " }\n" + 1934 " private void filler28() {\n" + 1935 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1936 " }\n" + 1937 " private void filler27() {\n" + 1938 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1939 " }\n" + 1940 " private void filler26() {\n" + 1941 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1942 " }\n" + 1943 " private void filler25() {\n" + 1944 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1945 " }\n" + 1946 " private void filler24() {\n" + 1947 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1948 " }\n" + 1949 " private void filler23() {\n" + 1950 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1951 " }\n" + 1952 " private void filler22() {\n" + 1953 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1954 " }\n" + 1955 " private void filler21() {\n" + 1956 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1957 " }\n" + 1958 " private void filler20() {\n" + 1959 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1960 " }\n" + 1961 " private void filler19() {\n" + 1962 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1963 " }\n" + 1964 " private void filler18() {\n" + 1965 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1966 " }\n" + 1967 " private void filler17() {\n" + 1968 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1969 " }\n" + 1970 " private void filler16() {\n" + 1971 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1972 " }\n" + 1973 " private void filler15() {\n" + 1974 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1975 " }\n" + 1976 " private void filler14() {\n" + 1977 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1978 " }\n" + 1979 " private void filler13() {\n" + 1980 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1981 " }\n" + 1982 " private void filler12() {\n" + 1983 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1984 " }\n" + 1985 " private void filler11() {\n" + 1986 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1987 " }\n" + 1988 " private void filler10() {\n" + 1989 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1990 " }\n" + 1991 " private void filler9() {\n" + 1992 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1993 " }\n" + 1994 " private void filler8() {\n" + 1995 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1996 " }\n" + 1997 " private void filler7() {\n" + 1998 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 1999 " }\n" + 2000 " private void filler6() {\n" + 2001 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 2002 " }\n" + 2003 " private void filler5() {\n" + 2004 " print( c.toString(), d.toString(), System.currentTimeMillis() );\n" + 2005 " }\n" + 2006 " private void filler4() {\n" + 2007 " print( a.toString(), b.toString(), System.currentTimeMillis() );\n" + 2008 " }\n" + 2009 " private void filler3() {\n" + 2010 " print( \"a\", System.getenv( \"asd\" ), System.currentTimeMillis() );\n" + 2011 " }\n" + 2012 " private void filler2() {\n" + 2013 " print( \"a\", System.lineSeparator(), System.currentTimeMillis() );\n" + 2014 " }\n" + 2015 " private void filler1() {\n" + 2016 " print( \"a\", \"b\", System.currentTimeMillis() );\n" + 2017 " }\n" + 2018 " private final Asd a = new Asd(\"a\");\n" + 2019 " private final Asd b = new Asd(\"b\");\n" + 2020 " private final Asd c = new Asd(\"c\");\n" + 2021 " private final Asd d = new Asd(\"d\");\n" + 2022 "}\n" 2023 }, 2024 options); 2025 } testbug497879()2026 public void testbug497879() { 2027 this.runConformTest( 2028 new String[]{ 2029 "LambdaSerializationTest.java", 2030 "import java.io.ByteArrayInputStream;\n" + 2031 "import java.io.ByteArrayOutputStream;\n" + 2032 "import java.io.IOException;\n" + 2033 "import java.io.ObjectInputStream;\n" + 2034 "import java.io.ObjectOutputStream;\n" + 2035 "import java.io.Serializable;\n" + 2036 "import java.util.ArrayList;\n" + 2037 "import java.util.List;\n" + 2038 "import java.util.function.Supplier;\n" + 2039 "public class LambdaSerializationTest {\n" + 2040 " interface SerializableSupplier<T> extends Supplier<T>, Serializable {}\n" + 2041 " public static void constructorReferenceSerialization() throws IOException, ClassNotFoundException {\n" + 2042 " SerializableSupplier<List<?>> function = ArrayList::new; //Collections::emptyList;\n" + 2043 " Object result = serializeDeserialize(function);\n" + 2044 " Class<?>[] infs = result.getClass().getInterfaces();\n" + 2045 " for(int i = 0; i < infs.length; i++) {\n" + 2046 " System.out.println(infs[i]);\n" + 2047 " }\n" + 2048 " }\n" + 2049 " private static Object serializeDeserialize(Object obj) throws IOException, ClassNotFoundException {\n" + 2050 " try (\n" + 2051 " ByteArrayOutputStream buffer = new ByteArrayOutputStream(); //\n" + 2052 " ObjectOutputStream output = new ObjectOutputStream(buffer)) {\n" + 2053 " output.writeObject(obj);\n" + 2054 " try (ObjectInputStream input = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()))) {\n" + 2055 " return input.readObject();\n" + 2056 " }\n" + 2057 " }\n" + 2058 " }\n" + 2059 " public static void main(String[] args) {\n" + 2060 " try {\n" + 2061 " LambdaSerializationTest.constructorReferenceSerialization();\n" + 2062 " } catch (ClassNotFoundException | IOException e) {\n" + 2063 " // TODO Auto-generated catch block\n" + 2064 " e.printStackTrace();\n" + 2065 " }\n" + 2066 " }\n" + 2067 "}" 2068 }, 2069 "interface LambdaSerializationTest$SerializableSupplier", 2070 null,true, 2071 new String[]{"-Ddummy"}); 2072 } testbug497879a()2073 public void testbug497879a() { 2074 this.runConformTest( 2075 new String[]{ 2076 "LambdaSerializationTest.java", 2077 "import java.io.ByteArrayInputStream;\n" + 2078 "import java.io.ByteArrayOutputStream;\n" + 2079 "import java.io.IOException;\n" + 2080 "import java.io.ObjectInputStream;\n" + 2081 "import java.io.ObjectOutputStream;\n" + 2082 "import java.io.Serializable;\n" + 2083 "import java.util.ArrayList;\n" + 2084 "import java.util.List;\n" + 2085 "import java.util.function.Supplier;\n" + 2086 "public class LambdaSerializationTest {\n" + 2087 " interface SerializableSupplier<T> extends Supplier<T>, Serializable {}\n" + 2088 " static class Junk {\n" + 2089 " private Junk() {}\n" + 2090 " }\n" + 2091 " public static void constructorReferenceSerialization() throws IOException, ClassNotFoundException {\n" + 2092 " SerializableSupplier<Junk> function = Junk::new;\n" + 2093 " Object result = serializeDeserialize(function);\n" + 2094 " Class<?>[] infs = result.getClass().getInterfaces();\n" + 2095 " for(int i = 0; i < infs.length; i++) {\n" + 2096 " System.out.println(infs[i]);\n" + 2097 " }\n" + 2098 " }\n" + 2099 " private static Object serializeDeserialize(Object obj) throws IOException, ClassNotFoundException {\n" + 2100 " try (\n" + 2101 " ByteArrayOutputStream buffer = new ByteArrayOutputStream(); //\n" + 2102 " ObjectOutputStream output = new ObjectOutputStream(buffer)) {\n" + 2103 " output.writeObject(obj);\n" + 2104 " try (ObjectInputStream input = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()))) {\n" + 2105 " return input.readObject();\n" + 2106 " }\n" + 2107 " }\n" + 2108 " }\n" + 2109 " public static void main(String[] args) {\n" + 2110 " try {\n" + 2111 " LambdaSerializationTest.constructorReferenceSerialization();\n" + 2112 " } catch (ClassNotFoundException | IOException e) {\n" + 2113 " // TODO Auto-generated catch block\n" + 2114 " e.printStackTrace();\n" + 2115 " }\n" + 2116 " }\n" + 2117 "}" 2118 }, 2119 "interface LambdaSerializationTest$SerializableSupplier", 2120 null,true, 2121 new String[]{"-Ddummy"}); 2122 } testbug497879b()2123 public void testbug497879b() { 2124 this.runConformTest( 2125 new String[]{ 2126 "LambdaSerializationTest.java", 2127 "import java.io.ByteArrayInputStream;\n" + 2128 "import java.io.ByteArrayOutputStream;\n" + 2129 "import java.io.IOException;\n" + 2130 "import java.io.ObjectInputStream;\n" + 2131 "import java.io.ObjectOutputStream;\n" + 2132 "import java.io.Serializable;\n" + 2133 "import java.util.ArrayList;\n" + 2134 "import java.util.List;\n" + 2135 "import java.util.function.Supplier;\n" + 2136 "public class LambdaSerializationTest {\n" + 2137 " interface SerializableSupplier<T> extends Serializable {\n" + 2138 " T get(int count);\n" + 2139 " }\n" + 2140 " public static void constructorReferenceSerialization() throws IOException, ClassNotFoundException {\n" + 2141 " SerializableSupplier<List[]> function = ArrayList[]::new;\n" + 2142 " Object result = serializeDeserialize(function);\n" + 2143 " Class<?>[] infs = result.getClass().getInterfaces();\n" + 2144 " for(int i = 0; i < infs.length; i++) {\n" + 2145 " System.out.println(infs[i]);\n" + 2146 " }\n" + 2147 " }\n" + 2148 " private static Object serializeDeserialize(Object obj) throws IOException, ClassNotFoundException {\n" + 2149 " try (\n" + 2150 " ByteArrayOutputStream buffer = new ByteArrayOutputStream(); //\n" + 2151 " ObjectOutputStream output = new ObjectOutputStream(buffer)) {\n" + 2152 " output.writeObject(obj);\n" + 2153 " try (ObjectInputStream input = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()))) {\n" + 2154 " return input.readObject();\n" + 2155 " }\n" + 2156 " }\n" + 2157 " }\n" + 2158 " public static void main(String[] args) {\n" + 2159 " try {\n" + 2160 " LambdaSerializationTest.constructorReferenceSerialization();\n" + 2161 " } catch (ClassNotFoundException | IOException e) {\n" + 2162 " // TODO Auto-generated catch block\n" + 2163 " e.printStackTrace();\n" + 2164 " }\n" + 2165 " }\n" + 2166 "}" 2167 }, 2168 "interface LambdaSerializationTest$SerializableSupplier", 2169 null,true, 2170 new String[]{"-Ddummy"}); 2171 } testbug503118()2172 public void testbug503118() { 2173 this.runConformTest( 2174 new String[]{ 2175 "lambdabug/App.java", 2176 "package lambdabug;\n" + 2177 "import java.io.ByteArrayInputStream;\n" + 2178 "import java.io.ByteArrayOutputStream;\n" + 2179 "import java.io.ObjectInputStream;\n" + 2180 "import java.io.ObjectOutputStream;\n" + 2181 "import java.io.Serializable;\n" + 2182 "import java.util.function.Function;\n" + 2183 "public class App {\n" + 2184 " public static interface SerialFunction<T, R> extends Function<T, R>, Serializable {\n" + 2185 " }\n" + 2186 " public static interface TestInterface extends Serializable {\n" + 2187 " public Integer method(Integer i);\n" + 2188 " }\n" + 2189 " public static class TestClass implements TestInterface {\n" + 2190 " private static final long serialVersionUID = 1L;\n" + 2191 " @Override\n" + 2192 " public Integer method(Integer i) {\n" + 2193 " return i;\n" + 2194 " }\n" + 2195 " }\n" + 2196 " public static void main(String[] args) throws Exception {\n" + 2197 " TestInterface testService = getService();\n" + 2198 " SerialFunction<Integer, Integer> sf = testService::method;\n" + 2199 " ByteArrayOutputStream bos = new ByteArrayOutputStream();\n" + 2200 " new ObjectOutputStream(bos).writeObject(sf);\n" + 2201 " Object o = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray())).readObject();\n" + 2202 " System.out.println(o.getClass().getInterfaces()[0]);\n" + 2203 " }\n" + 2204 " private static TestInterface getService() {\n" + 2205 " return new TestClass();\n" + 2206 " }\n" + 2207 "}\n" 2208 }, 2209 "interface lambdabug.App$SerialFunction", 2210 null,true, 2211 new String[]{"-Ddummy"}); 2212 } testbug507011()2213 public void testbug507011() { 2214 this.runConformTest( 2215 new String[]{ 2216 "VerifyErrorDerived.java", 2217 "import java.io.Serializable;\n" + 2218 "import java.util.function.Function;\n" + 2219 "public class VerifyErrorDerived extends VerifyErrorBase {\n" + 2220 " public static void main(String [] args) {\n" + 2221 " System.out.println(\"hello world\");\n" + 2222 " }\n" + 2223 " public int derivedMethod(String param) {\n" + 2224 " SerializableFunction<String, Integer> f = super::baseMethod;\n" + 2225 " return f.apply(param);\n" + 2226 " }\n" + 2227 "}\n" + 2228 "interface SerializableFunction<T, R> extends Function<T, R>, Serializable {}", 2229 "VerifyErrorBase.java", 2230 "public class VerifyErrorBase {\n" + 2231 " public int baseMethod(String param) {\n" + 2232 " return 7;\n" + 2233 " }\n" + 2234 "}\n" 2235 }, 2236 "hello world", 2237 null,true, 2238 new String[]{"-Ddummy"}); 2239 } testbug509782()2240 public void testbug509782() { 2241 this.runConformTest( 2242 new String[]{ 2243 "compilertest/BaseType.java", 2244 "package compilertest;\n" + 2245 "import java.io.ByteArrayInputStream;\n" + 2246 "import java.io.ByteArrayOutputStream;\n" + 2247 "import java.io.ObjectInputStream;\n" + 2248 "import java.io.ObjectOutputStream;\n" + 2249 "import java.io.Serializable;\n" + 2250 "import compilertest.sub.SubType;\n" + 2251 "public class BaseType implements Serializable {\n" + 2252 " protected void doSomething() {\n" + 2253 " }\n" + 2254 " public static void main(String[] args) throws Exception {\n" + 2255 " SubType instance = new SubType();\n" + 2256 " ByteArrayOutputStream bs = new ByteArrayOutputStream();\n" + 2257 " ObjectOutputStream out = new ObjectOutputStream(bs);\n" + 2258 " out.writeObject(instance);\n" + 2259 " byte[] data = bs.toByteArray();\n" + 2260 " ObjectInputStream in = new ObjectInputStream(\n" + 2261 " new ByteArrayInputStream(data));\n" + 2262 " in.readObject();\n" + 2263 " System.out.println(\"Done\");\n" + 2264 " }\n" + 2265 "}", 2266 "compilertest/sub/SubType.java", 2267 "package compilertest.sub;\n" + 2268 "import java.io.Serializable;\n" + 2269 "import compilertest.BaseType;\n" + 2270 "public class SubType extends BaseType {\n" + 2271 " Runnable task = (Runnable & Serializable) this::doSomething;\n" + 2272 "}\n" 2273 }, 2274 "Done", 2275 null,true, 2276 new String[]{"-Ddummy"}); 2277 } 2278 // --- 2279 checkExpected(String expected, String actual)2280 private void checkExpected(String expected, String actual) { 2281 if (!expected.equals(actual)) { 2282 printIt(actual); 2283 } 2284 assertEquals(expected,actual); 2285 } 2286 2287 /** 2288 * Print a piece of text with the necessary extra quotes and newlines so that it can be cut/pasted into 2289 * the test source file. 2290 */ printIt(String text)2291 private void printIt(String text) { 2292 String quotedText = text; 2293 if (!quotedText.startsWith("\"")) { 2294 quotedText = "\""+quotedText.replaceAll("\n", "\\\\n\"+\n\""); 2295 quotedText = quotedText.substring(0,quotedText.length()-3); 2296 } 2297 System.out.println(quotedText); 2298 } 2299 2300 /** 2301 * Print the bootstrap methods attribute in a very similar fashion to javap for checking. 2302 * Unlike javap the constant pool indexes are not included, to make the test a little less 2303 * fragile. 2304 */ printBootstrapMethodsAttribute(String filepath)2305 private String printBootstrapMethodsAttribute(String filepath) { 2306 IClassFileReader cfr = ToolFactory.createDefaultClassFileReader(filepath, IClassFileReader.CLASSFILE_ATTRIBUTES); 2307 BootstrapMethodsAttribute bootstrapMethodsAttribute = null; 2308 IClassFileAttribute[] attrs = cfr.getAttributes(); 2309 for (int i=0,max=attrs.length;i<max;i++) { 2310 if (new String(attrs[i].getAttributeName()).equals("BootstrapMethods")) { 2311 bootstrapMethodsAttribute = (BootstrapMethodsAttribute)attrs[i]; 2312 } 2313 } 2314 if (bootstrapMethodsAttribute==null) { 2315 return ""; 2316 } 2317 IConstantPool cp = cfr.getConstantPool(); 2318 StringBuffer sb = new StringBuffer(); 2319 int bmaLength = bootstrapMethodsAttribute.getBootstrapMethodsLength(); 2320 for (int i=0;i<bmaLength;i++) { 2321 IBootstrapMethodsEntry entry = bootstrapMethodsAttribute.getBootstrapMethods()[i]; 2322 int mr = entry.getBootstrapMethodReference(); 2323 IConstantPoolEntry2 icpe = (IConstantPoolEntry2)cfr.getConstantPool().decodeEntry(mr); 2324 2325 sb.append(i).append(": ").append(formatReferenceKind(icpe.getReferenceKind())); 2326 sb.append(" ").append(format(cp,icpe.getReferenceIndex())); 2327 sb.append("\n"); 2328 int[] args = entry.getBootstrapArguments(); 2329 sb.append(" Method arguments:\n"); 2330 for (int a=0;a<args.length;a++) { 2331 sb.append(" ").append(format(cp,args[a])).append("\n"); 2332 } 2333 } 2334 return sb.toString(); 2335 } 2336 printLambdaMethods(String filepath)2337 private String printLambdaMethods(String filepath) { 2338 IClassFileReader cfr = ToolFactory.createDefaultClassFileReader(filepath, IClassFileReader.METHOD_INFOS); 2339 IMethodInfo[] methodInfos = cfr.getMethodInfos(); 2340 StringBuffer buf = new StringBuffer(); 2341 for (int i = 0, max = methodInfos.length; i < max; i++) { 2342 IMethodInfo methodInfo = methodInfos[i]; 2343 if (!new String(methodInfo.getName()).startsWith("lambda")) 2344 continue; 2345 int accessFlags = methodInfo.getAccessFlags(); 2346 if (Modifier.isStatic(accessFlags)) { 2347 buf.append("static "); 2348 } 2349 buf.append(methodInfo.getName()); 2350 buf.append(methodInfo.getDescriptor()); 2351 buf.append("\n"); 2352 } 2353 return buf.toString(); 2354 } 2355 formatReferenceKind(int kind)2356 String formatReferenceKind(int kind) { 2357 switch (kind) { 2358 case IConstantPoolConstant.METHOD_TYPE_REF_InvokeStatic: 2359 return "invokestatic"; 2360 default: 2361 throw new IllegalStateException("nyi for "+kind); 2362 } 2363 } 2364 format(IConstantPool cp, int entryNumber)2365 String format(IConstantPool cp, int entryNumber) { 2366 IConstantPoolEntry entry = cp.decodeEntry(entryNumber); 2367 if (entry == null) { 2368 return "null"; 2369 } 2370 switch (entry.getKind()) { 2371 case IConstantPoolConstant.CONSTANT_Integer: 2372 return Integer.toString(entry.getIntegerValue()); 2373 case IConstantPoolConstant.CONSTANT_Utf8: 2374 return new String(entry.getUtf8Value()); 2375 case IConstantPoolConstant.CONSTANT_Methodref: 2376 return new String(entry.getClassName())+"."+new String(entry.getMethodName())+":"+new String(entry.getMethodDescriptor()); 2377 case IConstantPoolConstant.CONSTANT_MethodHandle: 2378 IConstantPoolEntry2 entry2 = (IConstantPoolEntry2)entry; 2379 return formatReferenceKind(entry2.getReferenceKind())+" "+format(cp,entry2.getReferenceIndex()); 2380 case IConstantPoolConstant.CONSTANT_MethodType: 2381 return format(cp,((IConstantPoolEntry2)entry).getDescriptorIndex()); 2382 case IConstantPoolConstant.CONSTANT_Class: 2383 return new String(entry.getClassInfoName()); 2384 default: 2385 throw new IllegalStateException("nyi for "+entry.getKind()); 2386 } 2387 } 2388 2389 } 2390 2391