1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 8046171
  27  * @summary Test the various rules for nest members and nest-tops
  28  * @compile -XDdisablePrivateAccessors
  29  *          TestNestmateMembership.java
  30  *          PackagedNestTop.java
  31  *          PackagedNestTop2.java
  32  *          NotAMember2.java
  33  * @compile MissingNestTop.jcod
  34  *          ArrayNestTop.jcod
  35  *          NotAMember.jcod
  36  *          NotAMember2.jcod
  37  *          PackagedNestTop.jcod
  38  *          PackagedNestTop2Member.jcod
  39  * @run main/othervm TestNestmateMembership
  40  */
  41 
  42 // We test all the "illegal" relationships between a nest member and its nest-top
  43 // except for the case where the name of the nest-member matches the name listed
  44 // in the nest-top, but resolves to a different class. There doesn't seem to
  45 // be a way to construct that scenario.
  46 // For each nested class below there is a corresponding .jcod file which breaks one
  47 // of the rules regarding nest membership. For the package related tests we have
  48 // additional PackageNestTop*.java sources. We also have NotAMember2.java.
  49 // Note that all the .java files must be compiled in the same step, while all
  50 // .jcod files must be compiled in a later step.
  51 
  52 public class TestNestmateMembership {
  53 
  54     // jcod modified to have non-existent nest-top
  55     static class MissingNestTop {
  56         private static void m() {
  57             System.out.println("MissingNestTop.m() - java version");
  58         }
  59     }
  60 
  61     // jcod modified to have non-instance class Object[] as nest-top
  62     static class ArrayNestTop {
  63         Object[] oa; // create CP entry
  64         private static void m() {
  65             System.out.println("ArrayTop.m() - java version");
  66         }
  67     }
  68 
  69     // jcod modified to have Object as nest-top, which has no nest-members
  70     static class NotAMember {
  71         private static void m() {
  72             System.out.println("NotAMember.m() - java version");
  73         }
  74     }
  75 
  76     public static void main(String[] args) throws Throwable {
  77         test_MissingNestTop();
  78         test_ArrayNestTop();
  79         test_WrongPackageForNestMember();
  80         test_NotAMember();
  81         test_NotAMember2();
  82     }
  83 
  84     static void test_WrongPackageForNestMember() {
  85         System.out.println("Testing for nest-top and nest-member in different packages");
  86         String msg = "Class P2.PackagedNestTop2$Member is in a different" +
  87                      " package to its nest top class P1.PackagedNestTop";
  88         try {
  89             P1.PackagedNestTop.doAccess();
  90             throw new Error("Missing IncompatibleClassChangeError: " + msg);
  91         }
  92         catch (IncompatibleClassChangeError expected) {
  93             if (!expected.getMessage().contains(msg))
  94                 throw new Error("Wrong IncompatibleClassChangeError: \"" +
  95                                 expected.getMessage() + "\" does not contain \"" +
  96                                 msg + "\"");
  97             System.out.println("OK - got expected exception: " + expected);
  98         }
  99     }
 100 
 101     static void test_MissingNestTop() throws Throwable {
 102         System.out.println("Testing for nest-top class that does not exist");
 103         String msg = "NoSuchClass";
 104         try {
 105             MissingNestTop.m();
 106             throw new Error("Missing NoClassDefFoundError: " + msg);
 107         }
 108         catch (NoClassDefFoundError expected) {
 109             if (!expected.getMessage().contains(msg))
 110                 throw new Error("Wrong NoClassDefFoundError: \"" +
 111                                 expected.getMessage() + "\" does not contain \"" +
 112                                 msg + "\"");
 113             System.out.println("OK - got expected exception: " + expected);
 114         }
 115     }
 116 
 117     static void test_ArrayNestTop() throws Throwable {
 118         System.out.println("Testing for nest-top class that is not an instance class");
 119         String msg = "ArrayNestTop has non-instance class [Ljava.lang.Object; as nest-top";
 120         try {
 121             ArrayNestTop.m();
 122             throw new Error("Missing IncompatibleClassChangeError: " + msg);
 123         }
 124         catch (IncompatibleClassChangeError expected) {
 125             if (!expected.getMessage().contains(msg))
 126                 throw new Error("Wrong IncompatibleClassChangeError: \"" +
 127                                 expected.getMessage() + "\" does not contain \"" +
 128                                 msg + "\"");
 129             System.out.println("OK - got expected exception: " + expected);
 130         }
 131     }
 132 
 133     static void test_NotAMember() throws Throwable {
 134         System.out.println("Testing for nest-top class that has no nest");
 135         String msg = "NotAMember is not a nest member of java.lang.Object";
 136         try {
 137             NotAMember.m();
 138             throw new Error("Missing IncompatibleClassChangeError: " + msg);
 139         }
 140         catch (IncompatibleClassChangeError expected) {
 141             if (!expected.getMessage().contains(msg))
 142                 throw new Error("Wrong IncompatibleClassChangeError: \"" +
 143                                 expected.getMessage() + "\" does not contain \"" +
 144                                 msg + "\"");
 145             System.out.println("OK - got expected exception: " + expected);
 146         }
 147     }
 148 
 149     static void test_NotAMember2() throws Throwable {
 150         System.out.println("Testing for nest-top class that doesn't list this class as a member");
 151         String msg = "NotAMember2$Member is not a nest member of TestNestmateMembership";
 152         try {
 153             NotAMember2.Member.m();
 154             throw new Error("Missing IncompatibleClassChangeError: " + msg);
 155         }
 156         catch (IncompatibleClassChangeError expected) {
 157             if (!expected.getMessage().contains(msg))
 158                 throw new Error("Wrong IncompatibleClassChangeError: \"" +
 159                                 expected.getMessage() + "\" does not contain \"" +
 160                                 msg + "\"");
 161             System.out.println("OK - got expected exception: " + expected);
 162         }
 163     }
 164 }