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 access to private methods between nestmates where there 28 * is an inheritance hierarchy and we invoke private methods that 29 * exist in specific classes in the hierarchy. 30 * @compile TestInvokeHierarchy.java 31 * @compile ExternalSuper.jcod ExternalSub.jcod 32 * @run main TestInvokeHierarchy 33 */ 34 35 public class TestInvokeHierarchy { 36 37 static class NestedA extends ExternalSuper { 38 static final String ID = "NestedA::priv_invoke"; 39 private String priv_invoke() { 40 return ID; 41 } 42 static void checkA(NestedA a) throws Throwable { 43 verifyEquals(a.priv_invoke(), NestedA.ID); 44 } 45 } 46 47 static class NestedB extends NestedA { 48 static final String ID = "NestedB::priv_invoke"; 49 private String priv_invoke() { 50 return ID; 51 } 52 static void checkA(NestedA a) throws Throwable { 53 verifyEquals(a.priv_invoke(), NestedA.ID); 54 } 55 } 56 57 static class NestedC extends NestedB { 58 static final String ID = "NestedC::priv_invoke"; 59 private String priv_invoke() { 60 return ID; 61 } 62 static void checkA(NestedA a) throws Throwable { 63 verifyEquals(a.priv_invoke(), NestedA.ID); 64 } 65 } 66 67 static void checkA(NestedA a) throws Throwable { 68 verifyEquals(a.priv_invoke(), NestedA.ID); 69 } 70 71 static void checkB(NestedB b) throws Throwable { 72 verifyEquals(b.priv_invoke(), NestedB.ID); 73 } 74 75 static void checkC(NestedC c) throws Throwable { 76 verifyEquals(c.priv_invoke(), NestedC.ID); 77 } 78 79 80 // Access to private members of classes outside the nest is 81 // not permitted. These tests should throw IllegalAccessError 82 // at runtime. To allow them to compile the classes below are 83 // defined with public members. We then replace those class files 84 // with jcod variants that make the member private again. 85 86 static void checkExternalSuper(ExternalSuper s) throws Throwable { 87 try { 88 String str = s.priv_invoke_s(); 89 throw new Error("Unexpected access to ExternalSuper.priv_invoke_s"); 90 } 91 catch (IllegalAccessError iae) { 92 System.out.println("Got expected exception accessing ExternalSuper.priv_invoke_s:" + iae); 93 } 94 } 95 96 static void checkExternalSub(ExternalSub s) throws Throwable { 97 try { 98 String str = s.priv_invoke(); 99 throw new Error("Unexpected access to ExternalSub.priv_invoke"); 100 } 101 catch (IllegalAccessError iae) { 102 System.out.println("Got expected exception accessing ExternalSub.priv_invoke:" + iae); 103 } 104 } 105 106 static void verifyEquals(String actual, String expected) { 107 if (!actual.equals(expected)) { 108 throw new Error("Expected " + expected + " but got " + actual); 109 } 110 System.out.println("Check passed for " + expected); 111 } 112 113 public static void main(String[] args) throws Throwable { 114 NestedA a = new NestedA(); 115 NestedB b = new NestedB(); 116 NestedC c = new NestedC(); 117 ExternalSub sub = new ExternalSub(); 118 ExternalSuper sup = new ExternalSuper(); 119 120 checkExternalSuper(sup); 121 checkExternalSuper(a); 122 checkExternalSuper(b); 123 checkExternalSuper(c); 124 checkExternalSuper(sub); 125 126 checkA(a); 127 checkA(b); 128 checkA(c); 129 checkA(sub); 130 131 NestedA.checkA(a); 132 NestedA.checkA(b); 133 NestedA.checkA(c); 134 NestedA.checkA(sub); 135 136 NestedB.checkA(a); 137 NestedB.checkA(b); 138 NestedB.checkA(c); 139 NestedB.checkA(sub); 140 141 NestedC.checkA(a); 142 NestedC.checkA(b); 143 NestedC.checkA(c); 144 NestedC.checkA(sub); 145 146 checkB(b); 147 checkB(c); 148 checkB(sub); 149 150 checkC(c); 151 checkC(sub); 152 153 checkExternalSub(sub); 154 } 155 } 156 157 // Classes that are not part of the nest. 158 // Being non-public allows us to declare them in this file. 159 // The priv_invoke* member is public to allow this file to compile, but 160 // the jcod files change it back to private. 161 162 class ExternalSuper { 163 static final String ID = "ExternalSuper::priv_invoke_s"; 164 // Can't call this priv_invoke as subclasses make it less accessible 165 // which is not allowed. 166 public String priv_invoke_s() { 167 return ID; 168 } 169 } 170 171 172 class ExternalSub extends TestInvokeHierarchy.NestedC { 173 static final String ID = "ExternalSub::priv_invoke"; 174 public String priv_invoke() { 175 return ID; 176 } 177 }