Groovy 4 vs Java 17 sealed classes: can Groovy extend a sealed Java class?
0 reputation · 16 Sept 2021, 17:02 UTC
0 reputation · 16 Sept 2021, 17:02 UTC
The goal is to determine whether Groovy 4 can legally extend a sealed Java 17 class or interface, and if so, how the compiler and runtime enforce the sealed hierarchy.
Current observations indicate that Groovy 4’s compiler accepts subclasses of sealed Java types that are not listed in the permits clause, but the resulting bytecode may trigger an IllegalAccessError at class loading time. Additionally, the @CompileStatic annotation does not appear to perform compile‑time checks against sealed contracts.
Key constraints include:
Given these observations, the unresolved questions are:
@CompileStatic to catch sealed hierarchy violations, or is runtime error the only safeguard?Groovy 4 can compile a subclass that extends a Java 17 sealed class or interface, but the JVM will reject the class at load time with an IllegalAccessError (or IncompatibleClassChangeError) if the subclass is not listed in the sealed type’s permits clause. The Groovy compiler does not emit a compile‑time diagnostic for this violation, and @CompileStatic does not add any sealed‑class validation.
permits rule during class loading.extends relationship.IllegalAccessError.@CompileStatic only enables compile‑time type checks; it does not add sealed‑class validation.// Base.java
sealed class Base permits Allowed {}
class Allowed extends Base {}
Compile with javac Base.java.
// Bad.groovy
class Bad extends Base {}
Compile with groovyc Bad.groovy.
public class Test {
public static void main(String[] args) {
try {
Class.forName("Bad");
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Run the program; you will see an IllegalAccessError indicating the sealed violation.
Because the compiler does not warn, you must rely on runtime checks or manual code review to avoid sealed violations. If you need early detection, consider adding a static analysis step or using a custom lint rule that inspects Groovy bytecode for forbidden superclasses.
If you are not experiencing the runtime error when loading the Groovy subclass, please confirm whether the class is actually referenced or loaded by the JVM. The error only occurs upon class initialization, so a class that is never loaded will not trigger the exception.
Use comments to ask for clarification. Post a solution as an answer.
32,775 reputation · 16 Sept 2021, 19:51 UTC
To further clarify the runtime failure, it is important to note that the IllegalAccessError occurs specifically during the verification phase of class loading. Because Groovy 4 generates standard JVM bytecode, it is subject to the same strict module‑aware checks as Java code, regardless of the source language.
For developers needing to verify why a Groovy subclass is being rejected without relying solely on stack traces, you can use the javap tool to inspect the generated class files:
javap -v YourGroovyClass to examine the class hierarchy.permits clause of the Java superclass to confirm the Groovy class is missing from the allowed list.Since @CompileStatic ignores these constraints, the only way to prevent these errors in current Groovy 4 environments is through manual architectural alignment or by using a Java‑based wrapper to define the permitted subclasses.