1 /* 2 * Copyright (c) 2022, 2024, 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 /* 26 * @ignore Fix JDK-8328417 27 * @test 28 * @summary test that the JVM correctly accepts or rejects classes based on their 29 * ACC_VALUE/ACC_IDENTITY modifiers 30 * @library /test/lib 31 * @enablePreview 32 * @compile NeutralInterface.java ValueInterface.java IdentityInterface.java 33 * @compile NeutralAbstract.java ValueAbstract.java IdentityAbstract.java AbstractWithField.java AbstractWithSynchMethod.java 34 * @compile ClassesWithInvalidModifiers.jcod 35 * @run main/othervm -verify TestClassModifiers 36 */ 37 38 import jdk.test.lib.Asserts; 39 40 public class TestClassModifiers { 41 static value class VC0 {} 42 static value class VC1 implements NeutralInterface { } 43 static value class VC2 implements ValueInterface { } 44 static value class VC3 extends NeutralAbstract { } 45 static value class VC4 extends ValueAbstract { } 46 static value class VC5 extends NeutralAbstract implements NeutralInterface { } 47 static value class VC6 extends NeutralAbstract implements ValueInterface { } 48 static value class VC7 extends ValueAbstract implements NeutralInterface { } 49 static value class VC8 extends ValueAbstract implements ValueInterface { } 50 51 static identity class IC0 { } 52 static identity class IC1 implements NeutralInterface { } 53 static identity class IC2 implements IdentityInterface { } 54 static identity class IC3 extends NeutralAbstract { } 55 static identity class IC4 extends IdentityAbstract { } 56 static identity class IC5 extends AbstractWithField { } 57 static identity class IC6 extends AbstractWithSynchMethod { } 58 static identity class IC7 extends NeutralAbstract implements NeutralInterface { } 59 static identity class IC8 extends NeutralAbstract implements IdentityInterface { } 60 static identity class IC9 extends IdentityAbstract implements NeutralInterface { } 61 static identity class IC10 extends IdentityAbstract implements IdentityInterface { } 62 63 64 static abstract class AC0 extends AbstractWithField implements NeutralInterface { } 65 static abstract class AC1 extends AbstractWithField implements IdentityInterface { } 66 static abstract class AC2 extends AbstractWithSynchMethod implements NeutralInterface { } 67 static abstract class AC3 extends AbstractWithSynchMethod implements IdentityInterface { } 68 69 static String[] validClasses = {"VC0", "VC1", "VC2", "VC3", "VC4", "VC5", "VC6", "VC7", "VC8", 70 "IC0", "IC1", "IC2", "IC3", "IC4", "IC5", "IC6", "IC7", "IC8", "IC9", "IC10", 71 "AC0", "AC1", "AC2", "AC3"}; 72 73 static String[] invalidClassesWithICCE = {"ValueClassExtendingIdentityClass", "ValueClassExtendingAbstractClassWithField", 74 "ValueClassExtendingAbstractClassWithSynchMethod", "ValueClassImplementingIdentityInterface", 75 "IdentityClassExtendingValueClass", "IdentityClassImplementingValueInterface", 76 "AbstractClassWithFieldExtendingValueClass", "AbstractClassWithFieldImplementingValueInterface"}; 77 static String[] invalidClassesWithCFE = {"AbstractClassWithFieldWithNoIdentityModifier", "AbstractClassWithSynchMethodWithNoIdentityModifier", 78 "AbstractClassWithBothModifiers", "ConcreteClassWithNoModifiers"}; 79 80 public static void main(String[] args) throws Exception { 81 // testing valid cases first 82 try { 83 for (String name : validClasses) { 84 System.out.println("Trying to load "+name); 85 Class c = Class.forName("TestClassModifiers$"+name); 86 } 87 } catch(Throwable t) { 88 t.printStackTrace(); 89 throw t; 90 } 91 92 // Testing invalid cases 93 for (String name: invalidClassesWithICCE) { 94 boolean icce = false; 95 boolean otherException = false; 96 Throwable exception = null; 97 try { 98 System.out.println("Trying to load "+name); 99 Class c = Class.forName(name); 100 } catch (IncompatibleClassChangeError e) { 101 icce = true; 102 } catch (Throwable t) { 103 otherException = true; 104 exception = t; 105 } 106 Asserts.assertFalse(otherException, "Unexpected exception "+exception); 107 Asserts.assertTrue(icce, "IncompatibleClassChangeError not thrown"); 108 } 109 for (String name: invalidClassesWithCFE) { 110 boolean cfe = false; 111 boolean otherException = false; 112 Throwable exception = null; 113 try { 114 System.out.println("Trying to load "+name); 115 Class c = Class.forName(name); 116 } catch (ClassFormatError e) { 117 cfe = true; 118 } catch (Throwable t) { 119 otherException = true; 120 exception = t; 121 } 122 Asserts.assertFalse(otherException, "Unexpected exception "+exception); 123 Asserts.assertTrue(cfe, "ClassFormatError not thrown"); 124 } 125 } 126 }