Skip to content

Commit

Permalink
8246337: Add more JVM tests for sealed classes
Browse files Browse the repository at this point in the history
Add missing test cases for sealed interfaces and sealed classes.

Reviewed-by: dholmes, lfoltan
  • Loading branch information
Harold Seigel committed Jun 26, 2020
1 parent e7fa180 commit 51ddc2a
Show file tree
Hide file tree
Showing 12 changed files with 378 additions and 20 deletions.
95 changes: 95 additions & 0 deletions test/hotspot/jtreg/runtime/modules/SealedInterfaceModuleTest.java
@@ -0,0 +1,95 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/*
* @test
* @bug 8225056 8246337
* @modules java.base/jdk.internal.misc
* @library /test/lib ..
* @compile sealedP1/SuperInterface.jcod
* @compile --enable-preview --source ${jdk.version} sealedP1/C1.java sealedP2/C2.java sealedP3/C3.java
* @build sun.hotspot.WhiteBox
* @compile/module=java.base java/lang/ModuleHelper.java
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. --enable-preview -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SealedInterfaceModuleTest
*/

public class SealedInterfaceModuleTest {

// Test sub-classing a sealed super interface in a named module. In this test,
// sealed interface sealedP1/SuperInterface permits sealedP1.C1, sealedP2.C2, and
// sealedP3.C3. All three of those classes implement sealedP1/SuperInterface.

public static void main(String args[]) throws Throwable {
Object m1x, m2x;

// Get the class loader for SealedInterfaceModuleTest and assume it's also used
// to load the other classes.
ClassLoader this_cldr = AccessCheckRead.class.getClassLoader();

// Define a module for packages sealedP1 and sealedP2.
m1x = ModuleHelper.ModuleObject("module_one", this_cldr,
new String[] { "sealedP1", "sealedP2" });
ModuleHelper.DefineModule(m1x, false, "9.0", "m1x/here",
new String[] { "sealedP1", "sealedP2" });

// Define a module for package sealedP3 with the same class loader.
m2x = ModuleHelper.ModuleObject("module_two", this_cldr, new String[] { "sealedP3" });
ModuleHelper.DefineModule(m2x, false, "9.0", "m2x/there", new String[] { "sealedP3" });

// Make package sealedP1 in m1x visible to everyone because it contains
// the sealed super interface for C1, C2, and C3.
ModuleHelper.AddModuleExportsToAll(m1x, "sealedP1");
ModuleHelper.AddReadsModule(m2x, m1x);

// Test subtype in the same named package and named module as its super
// interface. This should succeed.
// Class sealedP1.C1 implements interface sealedP1.SuperInterface.
Class p1_C1_class = Class.forName("sealedP1.C1");

// Test non-public class in same module but different package than its
// super interface. This should throw ICCE.
// Class sealedP2.C2 implements interface class sealedP1.SuperInterface.
try {
Class p2_C2_class = Class.forName("sealedP2.C2");
throw new RuntimeException("Expected IncompatibleClassChangeError exception not thrown");
} catch (IncompatibleClassChangeError e) {
if (!e.getMessage().contains("cannot implement sealed interface")) {
throw new RuntimeException("Wrong IncompatibleClassChangeError exception thrown: " + e.getMessage());
}
}

// Test subtype in a different module than its super type. This should
// fail even though they have the same class loader.
// Class sealedP3.C3 implements interface sealedP1.SuperInterface.
try {
Class p3_C3_class = Class.forName("sealedP3.C3");
throw new RuntimeException("Expected IncompatibleClassChangeError exception not thrown");
} catch (IncompatibleClassChangeError e) {
if (!e.getMessage().contains("cannot implement sealed interface")) {
throw new RuntimeException("Wrong IncompatibleClassChangeError exception thrown: " + e.getMessage());
}
}

}
}
2 changes: 1 addition & 1 deletion test/hotspot/jtreg/runtime/modules/sealedP1/C1.java
Expand Up @@ -24,7 +24,7 @@
// Small class used by SealedModuleTest
package sealedP1;

public final class C1 extends sealedP1.SuperClass {
public final class C1 extends sealedP1.SuperClass implements sealedP1.SuperInterface {

public C1() { }
}
43 changes: 43 additions & 0 deletions test/hotspot/jtreg/runtime/modules/sealedP1/SuperClass.jcod
Expand Up @@ -103,3 +103,46 @@ class sealedP1/SuperClass {
} // end PermittedSubclasses
} // Attributes
} // end class sealedP1/SuperClass


// This is an empty interface that is needed because the subtypes used by test
// SealedModuleTest are also used by test SealedInterfaceModuleTest, which
// tests a sealed interface with this same name.
//
// package sealedP1;
// public interface SuperInterface { }
//
class sealedP1/SuperInterface {
0xCAFEBABE;
0; // minor version
60; // version
[7] { // Constant Pool
; // first element is empty
class #2; // #1 at 0x0A
Utf8 "sealedP1/SuperInterface"; // #2 at 0x0D
class #4; // #3 at 0x27
Utf8 "java/lang/Object"; // #4 at 0x2A
Utf8 "SourceFile"; // #5 at 0x3D
Utf8 "SuperInterface.java"; // #6 at 0x4A
} // Constant Pool

0x0601; // access [ ACC_PUBLIC ACC_INTERFACE ]
#1;// this_cpx
#3;// super_cpx

[0] { // Interfaces
} // Interfaces

[0] { // fields
} // fields

[0] { // methods
} // methods

[1] { // Attributes
Attr(#5, 2) { // SourceFile at 0x6E
#6;
} // end SourceFile
} // Attributes
} // end class sealedP1/SuperInterface

148 changes: 148 additions & 0 deletions test/hotspot/jtreg/runtime/modules/sealedP1/SuperInterface.jcod
@@ -0,0 +1,148 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

// This sealed class cannot be a java file because its permits clause names
// a class in another package causing javac to issue a compilation error.
//
// Sealed super interface used by SealedInterfaceModuleTest.
//
// package sealedP1;
//
// public sealed interface SuperInterface permits sealedP1.C1, sealedP2.C2, sealedP3.C3 { }
//
class sealedP1/SuperInterface {
0xCAFEBABE;
65535; // minor version
60; // version
[14] { // Constant Pool
; // first element is empty
class #2; // #1 at 0x0A
Utf8 "sealedP1/SuperInterface"; // #2 at 0x0D
class #4; // #3 at 0x27
Utf8 "java/lang/Object"; // #4 at 0x2A
Utf8 "SourceFile"; // #5 at 0x3D
Utf8 "SuperInterface.java"; // #6 at 0x4A
Utf8 "PermittedSubclasses"; // #7 at 0x60
class #9; // #8 at 0x76
Utf8 "sealedP1/C1"; // #9 at 0x79
class #11; // #10 at 0x87
Utf8 "sealedP2/C2"; // #11 at 0x8A
class #13; // #12 at 0x98
Utf8 "sealedP3/C3"; // #13 at 0x9B
} // Constant Pool

0x0601; // access [ ACC_PUBLIC ACC_INTERFACE ]
#1;// this_cpx
#3;// super_cpx

[0] { // Interfaces
} // Interfaces

[0] { // fields
} // fields

[0] { // methods
} // methods

[2] { // Attributes
Attr(#5, 2) { // SourceFile at 0xB7
#6;
} // end SourceFile
;
Attr(#7, 8) { // PermittedSubclasses at 0xBF
0x00030008000A000C;
} // end PermittedSubclasses
} // Attributes
} // end class sealedP1/SuperInterface


// This is an empty class that is needed because the subtypes used by test
// SealedInterfaceModuleTest are also used by test SealedoduleTest, which
// tests a sealed class with this same name.
//
// package sealedP1;
//
// public class SuperClass { }
//
class sealedP1/SuperClass {
0xCAFEBABE;
0; // minor version
60; // version
[13] { // Constant Pool
; // first element is empty
Method #2 #3; // #1 at 0x0A
class #4; // #2 at 0x0F
NameAndType #5 #6; // #3 at 0x12
Utf8 "java/lang/Object"; // #4 at 0x17
Utf8 "<init>"; // #5 at 0x2A
Utf8 "()V"; // #6 at 0x33
class #8; // #7 at 0x39
Utf8 "sealedP1/SuperClass"; // #8 at 0x3C
Utf8 "Code"; // #9 at 0x52
Utf8 "LineNumberTable"; // #10 at 0x59
Utf8 "SourceFile"; // #11 at 0x6B
Utf8 "SuperClass.java"; // #12 at 0x78
} // Constant Pool

0x0021; // access [ ACC_PUBLIC ACC_SUPER ]
#7;// this_cpx
#2;// super_cpx

[0] { // Interfaces
} // Interfaces

[0] { // fields
} // fields

[1] { // methods
{ // Member at 0x96
0x0001; // access
#5; // name_cpx
#6; // sig_cpx
[1] { // Attributes
Attr(#9, 29) { // Code at 0x9E
1; // max_stack
1; // max_locals
Bytes[5]{
0x2AB70001B1;
}
[0] { // Traps
} // end Traps
[1] { // Attributes
Attr(#10, 6) { // LineNumberTable at 0xB5
[1] { // LineNumberTable
0 3; // at 0xC1
}
} // end LineNumberTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods

[1] { // Attributes
Attr(#11, 2) { // SourceFile at 0xC3
#12;
} // end SourceFile
} // Attributes
} // end class sealedP1/SuperClass
2 changes: 1 addition & 1 deletion test/hotspot/jtreg/runtime/modules/sealedP2/C2.java
Expand Up @@ -24,6 +24,6 @@
// Small class used by SealedModuleTest
package sealedP2;

final class C2 extends sealedP1.SuperClass {
final class C2 extends sealedP1.SuperClass implements sealedP1.SuperInterface {
public void method2() { }
}
2 changes: 1 addition & 1 deletion test/hotspot/jtreg/runtime/modules/sealedP3/C3.java
Expand Up @@ -24,6 +24,6 @@
// Small class used by SealedModuleTest
package sealedP3;

public final class C3 extends sealedP1.SuperClass {
public final class C3 extends sealedP1.SuperClass implements sealedP1.SuperInterface {
public void method3() { }
}
Expand Up @@ -26,13 +26,13 @@
//
// package Pkg;
//
// sealed public interface SealedInterface permits Permitted, otherPkg.WrongPackage { }
// sealed public interface SealedInterface permits Permitted, otherPkg.WrongPackage, otherPkg.WrongPackageNotPublic { }

class Pkg/SealedInterface {
0xCAFEBABE;
65535; // minor version
60; // version
[12] { // Constant Pool
[14] { // Constant Pool
; // first element is empty
class #2; // #1 at 0x0A
Utf8 "Pkg/SealedInterface"; // #2 at 0x0D
Expand All @@ -45,6 +45,8 @@ class Pkg/SealedInterface {
Utf8 "Pkg/Permitted"; // #9 at 0x74
class #11; // #10 at 0x84
Utf8 "otherPkg/WrongPackage"; // #11 at 0x87
class #13; // #12
Utf8 "otherPkg/WrongPackageNotPublic"; // #13
} // Constant Pool

0x0601; // access [ ACC_PUBLIC ACC_INTERFACE ]
Expand All @@ -65,8 +67,8 @@ class Pkg/SealedInterface {
#6;
} // end SourceFile
;
Attr(#7, 6) { // PermittedSubtclasses at 0xB5
0x00020008000A;
Attr(#7, 8) { // PermittedSubtclasses at 0xB5
0x00030008000A000C;
} // end PermittedSubclasses
} // Attributes
} // end class Pkg/SealedInterface

0 comments on commit 51ddc2a

Please sign in to comment.