You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (Jira)" <ji...@apache.org> on 2022/04/05 11:04:00 UTC

[jira] [Commented] (GROOVY-10565) JDK 17: Sealed classes inside a package cause Exception in thread "main" java.lang.ClassFormatError: Illegal class name

    [ https://issues.apache.org/jira/browse/GROOVY-10565?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17517378#comment-17517378 ] 

Paul King commented on GROOVY-10565:
------------------------------------

Thanks for the excellent detective work. We have a bug in the format we are writing for permitted subclass names. It doesn't occur when compiling the whole script, e.g. in the groovyConsole, but once written to bytecode, packages will cause problems. Earlier Groovy versions emulating sealed classes also have no problems.

> JDK 17: Sealed classes inside a package cause Exception in thread "main" java.lang.ClassFormatError: Illegal class name
> -----------------------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-10565
>                 URL: https://issues.apache.org/jira/browse/GROOVY-10565
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 4.0.0, 4.0.1
>            Reporter: Szymon Stępniak
>            Assignee: Paul King
>            Priority: Major
>
> I have found an issue with using sealed types that are inside a package. I took the example from the Groovy 4 release notes and I run it successfully - all classes in this example use the default package. However, when I took the same code and I put it in any package (e.g. `example` package), the execution started failing with:
> {code:bash}
> Exception in thread "main" java.lang.ClassFormatError: Illegal class name "example.Empty" in class file example/Tree
>         at java.base/java.lang.ClassLoader.defineClass1(Native Method)
>         at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
>         at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
>         at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
>         at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
>         at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
>         at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
>         at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
>         at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
>         at java.base/java.lang.ClassLoader.defineClass1(Native Method)
>         at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
>         at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
>         at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
>         at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
>         at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
>         at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
>         at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
>         at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
>         at example.notworking.run(notworking.groovy:20)
>         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
>         at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>         at java.base/java.lang.reflect.Method.invoke(Method.java:568)
>         at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:343)
>         at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:328)
>         at groovy.lang.MetaClassImpl.doInvokeMethod(MetaClassImpl.java:1369)
>         at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1103)
>         at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1009)
>         at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:610)
>         at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:593)
>         at org.codehaus.groovy.runtime.InvokerHelper.runScript(InvokerHelper.java:413)
>         at org.codehaus.groovy.runtime.InvokerHelper$runScript.callStatic(Unknown Source)
>         at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:54)
>         at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:217)
>         at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:240)
>         at example.notworking.main(notworking.groovy)
> {code}
> Here is the code that produces this error:
> {code:groovy}
> package example
> import groovy.transform.Canonical
> sealed interface Tree<T> {}
> @Singleton final class Empty implements Tree {
>     String toString() { 'Empty' }
> }
> @Canonical final class Node<T> implements Tree<T> {
>     T value
>     Tree<T> left, right
>     String toString() {
>         "Node($value, $left, $right)"
>     }
> }
> Tree<Integer> tree = new Node<Integer>(42, new Node<>(0, Empty.instance, Empty.instance), Empty.instance)
> assert tree.toString() == 'Node(42, Node(0, Empty, Empty), Empty)'
> println "IT WORKS!"
> {code}
> One important note: this error shows up when I use Java 17. If I run the same code with Java 8 or Java 11, all works fine.
> Also one thing: this problem does not occur in plain Java (I attached such an example in the repository below).
> I created an exemplary Gradle project that reproduces this issue - [https://github.com/wololock/groovy-4-sealed-issue]



--
This message was sent by Atlassian Jira
(v8.20.1#820001)