1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2018 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /**
  26  * @test
  27  * @summary Test extended ArrayIndexOutOfBoundsException message for
  28  *   class files generated without debug information. The message lists
  29  *   information about the array and the indexes involved.
  30  * @compile ArrayIndexOutOfBoundsExceptionTest.java
  31  * @run testng ArrayIndexOutOfBoundsExceptionTest
  32  * @run testng/othervm -Xcomp -XX:-TieredCompilation  ArrayIndexOutOfBoundsExceptionTest
  33  * @run testng/othervm -Xcomp -XX:TieredStopAtLevel=1 ArrayIndexOutOfBoundsExceptionTest
  34  * @author Ann-Kathrin Wasle
  35  */
  36 
  37 import java.io.ByteArrayInputStream;
  38 import java.io.ByteArrayOutputStream;
  39 import java.io.ObjectInputStream;
  40 import java.io.ObjectOutputStream;
  41 import java.util.ArrayList;
  42 
  43 import org.testng.annotations.Test;
  44 
  45 import static org.testng.Assert.assertEquals;
  46 import static org.testng.Assert.assertNull;
  47 import static org.testng.Assert.assertNotNull;
  48 import static org.testng.Assert.assertTrue;
  49 import static org.testng.Assert.fail;
  50 
  51 /**
  52  * Tests the detailed messages for the ArrayIndexOutOfBoundsException.
  53  */
  54 public class ArrayIndexOutOfBoundsExceptionTest {
  55 
  56     // Some fields used in the test.
  57     static int[] staticArray = new int[0];
  58     static long[][] staticLongArray = new long[0][0];
  59     DoubleArrayGen dag;
  60     ArrayList<String> names = new ArrayList<>();
  61     ArrayList<String> curr;
  62     static boolean hasDebugInfo = true;
  63     static boolean noBetterUnknownLocals = true;
  64 
  65     static {
  66         try {
  67             hasDebugInfo = System.getProperty("hasDebugInfo") != null;
  68             noBetterUnknownLocals = System.getProperty("noBetterUnknownLocals") != null;
  69         } catch (Throwable t) { throw new RuntimeException(t); }
  70     }
  71 
  72     public static void main(String[] args) {
  73         ArrayIndexOutOfBoundsExceptionTest t = new ArrayIndexOutOfBoundsExceptionTest();
  74         try {
  75             t.testCreationViaNew();
  76             t.testCreationViaReflection();
  77             t.testCreationViaSerialization();
  78             t.testLoadedFromLocalVariable1();
  79             t.testLoadedFromLocalVariable2();
  80             t.testLoadedFromLocalVariable3();
  81             t.testLoadedFromLocalVariable4();
  82             t.testLoadedFromLocalVariable5();
  83             t.testLoadedFromLocalVariable6();
  84             t.testLoadedFromLocalVariable7();
  85             t.testLoadedFromLocalVariable8();
  86             t.testLoadedFromLocalVariable9();
  87             t.testLoadedFromLocalVariable10();
  88             t.testLoadedFromLocalVariable11();
  89             t.testLoadedFromMethod1();
  90             t.testLoadedFromMethod2();
  91             t.testLoadedFromMethod3();
  92             t.testLoadedFromMethod4();
  93             t.testLoadedFromStaticField1();
  94             t.testLoadedFromStaticField2();
  95             t.testLoadedFromStaticField3();
  96             t.testLoadedFromStaticField4();
  97             t.testWorkWithCompiler();
  98             t.testMissingLocalVariableTable();
  99             t.testAIOOBMessages();
 100         } catch (Exception e) {}
 101     }
 102 
 103     /**
 104      *
 105      */
 106     @Test
 107     public void testCreationViaNew() {
 108         assertNull(new ArrayIndexOutOfBoundsException().getMessage());
 109     }
 110 
 111     /**
 112      * @throws Exception
 113      */
 114     @Test
 115     public void testCreationViaReflection() throws Exception {
 116         Exception ex = ArrayIndexOutOfBoundsException.class.newInstance();
 117         assertNull(ex.getMessage());
 118     }
 119 
 120     /**
 121      * @throws Exception
 122      */
 123     @Test
 124     public void testCreationViaSerialization() throws Exception {
 125         Object o = new ArrayIndexOutOfBoundsException();
 126         ByteArrayOutputStream bos = new ByteArrayOutputStream();
 127         ObjectOutputStream oos = new ObjectOutputStream(bos);
 128         oos.writeObject(o);
 129         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
 130         ObjectInputStream ois = new ObjectInputStream(bis);
 131         Exception ex = (Exception) ois.readObject();
 132         assertNull(ex.getMessage());
 133     }
 134 
 135     /**
 136      *
 137      */
 138     @Test
 139     public void testLoadedFromLocalVariable1() {
 140         Object[] a = new Object[5];
 141 
 142         try {
 143             a[10].hashCode();
 144             fail();
 145         } catch (ArrayIndexOutOfBoundsException e) {
 146             e.printStackTrace();
 147             assertNotNull(e.getMessage());
 148         }
 149     }
 150 
 151     /**
 152      *
 153      */
 154     @Test
 155     public void testLoadedFromLocalVariable2() {
 156         Object[] a = new Object[7];
 157 
 158         try {
 159             a[-7] = null;
 160             fail();
 161         } catch (ArrayIndexOutOfBoundsException e) {
 162             e.printStackTrace();
 163             assertNotNull(e.getMessage());
 164         }
 165     }
 166 
 167     /**
 168      *
 169      */
 170     @Test
 171     public void testLoadedFromLocalVariable3() {
 172         byte[] a = new byte[0];
 173 
 174         try {
 175             assertTrue(a[99] == 5);
 176             fail();
 177         } catch (ArrayIndexOutOfBoundsException e) {
 178             e.printStackTrace();
 179             assertNotNull(e.getMessage());
 180         }
 181     }
 182 
 183     /**
 184      *
 185      */
 186     @Test
 187     public void testLoadedFromLocalVariable4() {
 188         char[] a = new char[0];
 189 
 190         try {
 191             a[0] = 0;
 192             fail();
 193         } catch (ArrayIndexOutOfBoundsException e) {
 194             e.printStackTrace();
 195             assertNotNull(e.getMessage());
 196         }
 197     }
 198 
 199     /**
 200      *
 201      */
 202     @Test
 203     public void testLoadedFromLocalVariable5() {
 204         double[] a = new double[0];
 205 
 206         try {
 207             assertTrue(a[0] == 0);
 208             fail();
 209         } catch (ArrayIndexOutOfBoundsException e) {
 210             e.printStackTrace();
 211             assertNotNull(e.getMessage());
 212         }
 213     }
 214 
 215     /**
 216      *
 217      */
 218     @Test
 219     public void testLoadedFromLocalVariable6() {
 220         float[] a = new float[0];
 221 
 222         try {
 223             a[0] = 0;
 224             fail();
 225         } catch (ArrayIndexOutOfBoundsException e) {
 226             e.printStackTrace();
 227             assertNotNull(e.getMessage());
 228         }
 229     }
 230 
 231     /**
 232      *
 233      */
 234     @Test
 235     public void testLoadedFromLocalVariable7() {
 236         int[] a = new int[0];
 237 
 238         try {
 239             assertTrue(a[0] == 0);
 240             fail();
 241         } catch (ArrayIndexOutOfBoundsException e) {
 242             e.printStackTrace();
 243             assertNotNull(e.getMessage());
 244         }
 245     }
 246 
 247     /**
 248      *
 249      */
 250     @Test
 251     public void testLoadedFromLocalVariable8() {
 252         long[] a = new long[0];
 253 
 254         try {
 255             a[0] = 0;
 256             fail();
 257         } catch (ArrayIndexOutOfBoundsException e) {
 258             e.printStackTrace();
 259             assertNotNull(e.getMessage());
 260         }
 261     }
 262 
 263     /**
 264      *
 265      */
 266     @Test
 267     public void testLoadedFromLocalVariable9() {
 268         short[] a = new short[5];
 269 
 270         try {
 271             assertTrue(a[10] == 0);
 272             fail();
 273         } catch (ArrayIndexOutOfBoundsException e) {
 274             e.printStackTrace();
 275             assertNotNull(e.getMessage());
 276         }
 277     }
 278 
 279     /**
 280      *
 281      */
 282     @Test
 283     public void testLoadedFromLocalVariable10() {
 284         int[][][] a = new int[1][0][0];
 285 
 286         try {
 287             assertTrue(a[0][1][2] == 0);
 288             fail();
 289         } catch (ArrayIndexOutOfBoundsException e) {
 290             e.printStackTrace();
 291             assertNotNull(e.getMessage());
 292         }
 293     }
 294 
 295     /**
 296      *
 297      */
 298     @Test
 299     public void testLoadedFromLocalVariable11() {
 300         int[][][] a = new int[1][0][0];
 301 
 302         try {
 303             a[0][1][2] = 0;
 304             fail();
 305         } catch (ArrayIndexOutOfBoundsException e) {
 306             e.printStackTrace();
 307             assertNotNull(e.getMessage());
 308         }
 309     }
 310 
 311     /**
 312      *
 313      */
 314     @Test
 315     public void testLoadedFromMethod1() {
 316 
 317         try {
 318             assertTrue((ArrayGenerator.arrayReturner(false))[0] == null);
 319             fail();
 320         } catch (ArrayIndexOutOfBoundsException e) {
 321             e.printStackTrace();
 322             assertNotNull(e.getMessage());
 323         }
 324     }
 325 
 326     /**
 327      *
 328      */
 329     @Test
 330     public void testLoadedFromMethod2() {
 331         try {
 332             assertTrue(
 333                ((new ArrayGenerator().returnMyArray(1, 1, (short) 1)))[0] == null);
 334             fail();
 335         } catch (ArrayIndexOutOfBoundsException e) {
 336             e.printStackTrace();
 337             assertNotNull(e.getMessage());
 338         }
 339     }
 340 
 341     /**
 342      *
 343      */
 344     @Test
 345     public void testLoadedFromMethod3() {
 346         try {
 347             assertTrue((returnArray(null, null, 1f))[0] == null);
 348             fail();
 349         } catch (ArrayIndexOutOfBoundsException e) {
 350             e.printStackTrace();
 351             assertNotNull(e.getMessage());
 352         }
 353     }
 354 
 355     /**
 356      *
 357      */
 358     @Test
 359     public void testLoadedFromMethod4() {
 360         ImplTestLoadedFromMethod4(new DoubleArrayGenImpl());
 361     }
 362 
 363     /**
 364      * @param gen
 365      */
 366     public void ImplTestLoadedFromMethod4(DoubleArrayGen gen) {
 367         try {
 368             (gen.getArray())[0] = 1.0;
 369             fail();
 370         } catch (ArrayIndexOutOfBoundsException e) {
 371             e.printStackTrace();
 372             assertNotNull(e.getMessage());
 373         }
 374     }
 375 
 376     /**
 377      *
 378      */
 379     @Test
 380     public void testLoadedFromStaticField1() {
 381         try {
 382             assertTrue(staticArray[0] == 1);
 383             fail();
 384         } catch (ArrayIndexOutOfBoundsException e) {
 385             e.printStackTrace();
 386             assertNotNull(e.getMessage());
 387         }
 388     }
 389 
 390     /**
 391      *
 392      */
 393     @Test
 394     public void testLoadedFromStaticField2() {
 395         try {
 396             staticArray[0] = 2;
 397             fail();
 398         } catch (ArrayIndexOutOfBoundsException e) {
 399             e.printStackTrace();
 400             assertNotNull(e.getMessage());
 401         }
 402     }
 403 
 404     /**
 405      *
 406      */
 407     @Test
 408     public void testLoadedFromStaticField3() {
 409         try {
 410             assertTrue(staticLongArray[0][0] == 1L);
 411         } catch (ArrayIndexOutOfBoundsException e) {
 412             e.printStackTrace();
 413             assertNotNull(e.getMessage());
 414         }
 415     }
 416 
 417     /**
 418      *
 419      */
 420     @Test
 421     public void testLoadedFromStaticField4() {
 422         try {
 423             staticLongArray[0][0] = 2L;
 424             fail();
 425         } catch (ArrayIndexOutOfBoundsException e) {
 426             e.printStackTrace();
 427             assertNotNull(e.getMessage());
 428         }
 429     }
 430 
 431     /**
 432      *
 433      */
 434     @Test
 435     public void testWorkWithCompiler() {
 436         int[] a = {0, 1, 2};
 437         int i1 = 2;
 438         int i2 = 3;
 439 
 440         for (int i = 0; i < 10000000; i++) { // One 0 less is enough for d64.
 441             testImplWorkWithCompiler(a, i1);
 442         }
 443         testImplWorkWithCompiler(a, i2);
 444     }
 445 
 446     /**
 447      * @param a
 448      * @param i
 449      */
 450     public void testImplWorkWithCompiler(int[] a, int i) {
 451         try {
 452             assertTrue(a[i] == 2);
 453         } catch (ArrayIndexOutOfBoundsException e) {
 454             e.printStackTrace();
 455             assertNotNull(e.getMessage());
 456         }
 457     }
 458 
 459     private Object[] returnArray(String[][] dummy1, int[][][] dummy2, float dummy3) {
 460         return new Object[0];
 461     }
 462 
 463     /**
 464      *
 465      */
 466     public static interface DoubleArrayGen {
 467         /**
 468          * @return double Array
 469          */
 470         public double[] getArray();
 471     }
 472 
 473     /**
 474      *
 475      */
 476     public static class DoubleArrayGenImpl implements DoubleArrayGen {
 477         @Override
 478         public double[] getArray() {
 479             return new double[0];
 480         }
 481     }
 482 
 483     /**
 484      *
 485      */
 486     public static class ArrayGenerator {
 487 
 488         /**
 489          * @param dummy1
 490          * @return Object Array
 491          */
 492         public static Object[] arrayReturner(boolean dummy1) {
 493             return new Object[0];
 494         }
 495 
 496         /**
 497          * @param dummy1
 498          * @param dummy2
 499          * @param dummy3
 500          * @return Object Array
 501          */
 502         public Object[] returnMyArray(double dummy1, long dummy2, short dummy3) {
 503             return new Object[0];
 504         }
 505     }
 506 
 507 
 508     /**
 509      *
 510      */
 511     @Test
 512     public void testMissingLocalVariableTable() {
 513         doTestMissingLocalVariableTable(names);
 514 
 515         System.out.println("Names");
 516 
 517         for (int i = 0; i < names.size(); ++i) {
 518             System.out.println(names.get(i));
 519         }
 520 
 521         String[] expectedHasDebugInfoGoodNames = new String[] {
 522                 "trying to access index 0 of an array with length 0",
 523                 "while trying to load from index -1 of an object array with length 10, " +
 524                         "loaded from local variable 'o1'",
 525                 "while trying to store to index 1 of a byte (or boolean) array with length 0, " +
 526                         "loaded from local variable 'z1'",
 527                 "while trying to load from index 7 of an object array with length 5, " +
 528                         "loaded from local variable 'dd1'"
 529         };
 530 
 531         String[] expectedNoDebugInfoGoodNames = new String[] {
 532                 "trying to access index 0 of an array with length 0",
 533                 "trying to access index -1 of an array with length 10",
 534                 "trying to access index 1 of an array with length 0",
 535                 "trying to access index 7 of an array with length 5"
 536         };
 537 
 538         String[] expectedNoDebugInfoBadNames = new String[] {
 539                 "trying to access index 0 of an array with length 0",
 540                 "trying to access index -1 of an array with length 10",
 541                 "trying to access index 1 of an array with length 0",
 542                 "trying to access index 7 of an array with length 5"
 543         };
 544 
 545         String[] expectedNames;
 546         if (hasDebugInfo) {
 547             expectedNames = expectedHasDebugInfoGoodNames;
 548         } else {
 549             if (noBetterUnknownLocals) {
 550                 expectedNames = expectedNoDebugInfoBadNames;
 551             } else {
 552                 expectedNames = expectedNoDebugInfoGoodNames;
 553             }
 554         }
 555 
 556         assertEquals(expectedNames.length, names.size());
 557 
 558         for (int i = 0; i < expectedNames.length; ++i) {
 559             assertEquals(names.get(i), expectedNames[i]);
 560         }
 561     }
 562 
 563     private void doTestMissingLocalVariableTable(ArrayList<String> names) {
 564         curr = names;
 565         doTestMissingLocalVariableTable1();
 566         doTestMissingLocalVariableTable2(new Object[10], new boolean[0], new double[5][1]);
 567     }
 568 
 569     private void doTestMissingLocalVariableTable1() {
 570         try {
 571             staticArray[0] = 0;
 572             fail();
 573         }
 574         catch (ArrayIndexOutOfBoundsException e) {
 575             curr.add(e.getMessage());
 576         }
 577     }
 578 
 579     private void doTestMissingLocalVariableTable2(Object[] o1, boolean z1[], double[][] dd1) {
 580         try {
 581             o1[-1].hashCode();
 582             fail();
 583         }
 584         catch (ArrayIndexOutOfBoundsException e) {
 585             curr.add(e.getMessage());
 586         }
 587 
 588         try {
 589             z1[1] = true;
 590             fail();
 591         }
 592         catch (ArrayIndexOutOfBoundsException e) {
 593             curr.add(e.getMessage());
 594         }
 595 
 596         try {
 597             assertTrue(dd1[7][1] == 0);
 598             fail();
 599         }
 600         catch (ArrayIndexOutOfBoundsException e) {
 601             curr.add(e.getMessage());
 602         }
 603     }
 604 
 605     /**
 606      *
 607      */
 608     @Test
 609     public void testAIOOBMessages() {
 610         boolean[] za1 = new boolean[0];
 611         byte[]    ba1 = new byte[0];
 612         short[]   sa1 = new short[0];
 613 
 614         char[]    ca1 = new char[0];
 615         int[]     ia1 = new int[0];
 616         long[]    la1 = new long[0];
 617 
 618         float[]   fa1 = new float[0];
 619         double[]  da1 = new double[0];
 620         Object[]  oa1 = new Object[10];
 621 
 622         Object[]  oa2 = new Object[5];
 623 
 624         try {
 625             System.out.println(za1[-5]);
 626             fail();
 627         }
 628         catch (ArrayIndexOutOfBoundsException e) {
 629             assertEquals(e.getMessage(),
 630                 "trying to access index -5 of an array with length 0");
 631         }
 632 
 633         try {
 634             System.out.println(ba1[0]);
 635             fail();
 636         }
 637         catch (ArrayIndexOutOfBoundsException e) {
 638             assertEquals(e.getMessage(),
 639                 "trying to access index 0 of an array with length 0");
 640         }
 641 
 642         try {
 643             System.out.println(sa1[0]);
 644             fail();
 645         }
 646         catch (ArrayIndexOutOfBoundsException e) {
 647             assertEquals(e.getMessage(),
 648                 "trying to access index 0 of an array with length 0");
 649         }
 650 
 651         try {
 652             System.out.println(ca1[0]);
 653             fail();
 654         }
 655         catch (ArrayIndexOutOfBoundsException e) {
 656             assertEquals(e.getMessage(),
 657                 "trying to access index 0 of an array with length 0");
 658         }
 659 
 660         try {
 661             System.out.println(ia1[0]);
 662             fail();
 663         }
 664         catch (ArrayIndexOutOfBoundsException e) {
 665             assertEquals(e.getMessage(),
 666                 "trying to access index 0 of an array with length 0");
 667         }
 668 
 669         try {
 670             System.out.println(la1[0]);
 671             fail();
 672         }
 673         catch (ArrayIndexOutOfBoundsException e) {
 674             assertEquals(e.getMessage(),
 675                 "trying to access index 0 of an array with length 0");
 676         }
 677 
 678         try {
 679             System.out.println(fa1[0]);
 680             fail();
 681         }
 682         catch (ArrayIndexOutOfBoundsException e) {
 683             assertEquals(e.getMessage(),
 684                 "trying to access index 0 of an array with length 0");
 685         }
 686 
 687         try {
 688             System.out.println(da1[0]);
 689             fail();
 690         }
 691         catch (ArrayIndexOutOfBoundsException e) {
 692             assertEquals(e.getMessage(),
 693                 "trying to access index 0 of an array with length 0");
 694         }
 695 
 696         try {
 697             System.out.println(oa1[12]);
 698             fail();
 699         }
 700         catch (ArrayIndexOutOfBoundsException e) {
 701             assertEquals(e.getMessage(),
 702                 "trying to access index 12 of an array with length 10");
 703         }
 704 
 705         try {
 706             System.out.println(za1[0] = false);
 707             fail();
 708         }
 709         catch (ArrayIndexOutOfBoundsException e) {
 710             assertEquals(e.getMessage(),
 711                 "trying to access index 0 of an array with length 0");
 712         }
 713 
 714         try {
 715             System.out.println(ba1[0] = 0);
 716             fail();
 717         }
 718         catch (ArrayIndexOutOfBoundsException e) {
 719             assertEquals(e.getMessage(),
 720                 "trying to access index 0 of an array with length 0");
 721         }
 722 
 723         try {
 724             System.out.println(sa1[0] = 0);
 725             fail();
 726         }
 727         catch (ArrayIndexOutOfBoundsException e) {
 728             assertEquals(e.getMessage(),
 729                 "trying to access index 0 of an array with length 0");
 730         }
 731 
 732         try {
 733             System.out.println(ca1[0] = 0);
 734             fail();
 735         }
 736         catch (ArrayIndexOutOfBoundsException e) {
 737             assertEquals(e.getMessage(),
 738                 "trying to access index 0 of an array with length 0");
 739         }
 740 
 741         try {
 742             System.out.println(ia1[0] = 0);
 743             fail();
 744         }
 745         catch (ArrayIndexOutOfBoundsException e) {
 746             assertEquals(e.getMessage(),
 747                 "trying to access index 0 of an array with length 0");
 748         }
 749 
 750         try {
 751             System.out.println(la1[0] = 0);
 752             fail();
 753         }
 754         catch (ArrayIndexOutOfBoundsException e) {
 755             assertEquals(e.getMessage(),
 756                 "trying to access index 0 of an array with length 0");
 757         }
 758 
 759         try {
 760             System.out.println(fa1[0] = 0);
 761             fail();
 762         }
 763         catch (ArrayIndexOutOfBoundsException e) {
 764             assertEquals(e.getMessage(),
 765                 "trying to access index 0 of an array with length 0");
 766         }
 767 
 768         try {
 769             System.out.println(da1[0] = 0);
 770             fail();
 771         }
 772         catch (ArrayIndexOutOfBoundsException e) {
 773             assertEquals(e.getMessage(),
 774                 "trying to access index 0 of an array with length 0");
 775         }
 776 
 777         try {
 778             System.out.println(oa1[-2] = null);
 779             fail();
 780         }
 781         catch (ArrayIndexOutOfBoundsException e) {
 782             assertEquals(e.getMessage(),
 783                 "trying to access index -2 of an array with length 10");
 784         }
 785 
 786         try {
 787             assertTrue((ArrayGenerator.arrayReturner(false))[0] == null);
 788             fail();
 789         } catch (ArrayIndexOutOfBoundsException e) {
 790             assertEquals(e.getMessage(),
 791                 "trying to access index 0 of an array with length 0");
 792         }
 793         try {
 794             staticArray[0] = 2;
 795             fail();
 796         } catch (ArrayIndexOutOfBoundsException e) {
 797             assertEquals(e.getMessage(),
 798                 "trying to access index 0 of an array with length 0");
 799         }
 800 
 801         try {
 802             System.arraycopy(oa1, 8, oa2, 0, 5);
 803             fail();
 804         } catch (ArrayIndexOutOfBoundsException e) {
 805             assertEquals(e.getMessage(),
 806                 "while trying to copy from index 13 of an object array with length 10");
 807         }
 808     }
 809 }