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

[jira] [Updated] (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:all-tabpanel ]

Szymon Stępniak updated GROOVY-10565:
-------------------------------------
    Description: 
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]

  was:
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.

I created an exemplary Gradle project that reproduces this issue - https://github.com/wololock/groovy-4-sealed-issue


> 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
>            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)