Skip to content

GROOVY-12020: EnumSet.plus(element) loses EnumSet type under JPMS#2566

Merged
paulk-asert merged 1 commit into
apache:GROOVY_4_0_Xfrom
paulk-asert:GROOVY-12020
May 30, 2026
Merged

GROOVY-12020: EnumSet.plus(element) loses EnumSet type under JPMS#2566
paulk-asert merged 1 commit into
apache:GROOVY_4_0_Xfrom
paulk-asert:GROOVY-12020

Conversation

@paulk-asert
Copy link
Copy Markdown
Contributor

Under newer JDKs, ObjectUtil.cloneObject fails for EnumSet because the MethodHandles.Lookup, teleported into the concrete RegularEnumSet (a package-private subclass in java.base), lacks the access needed to unreflect the inherited public clone() method. The IllegalAccessException is swallowed by DefaultGroovyMethodsSupport.cloneObject's catch-all and cloneSimilarCollection falls back to LinkedHashSet, so

EnumSet.of(A, B, C) + D

now returns a LinkedHashSet instead of an EnumSet. Subsequent assignment to an EnumSet-typed variable or field then fails with a GroovyCastException.

Fall back to plain reflective Method.invoke when the MethodHandle Lookup cannot access clazz. The clone method itself is public, so reflective invocation succeeds without needing --add-opens.

Under newer JDKs, ObjectUtil.cloneObject fails for EnumSet because the
MethodHandles.Lookup, teleported into the concrete RegularEnumSet (a
package-private subclass in java.base), lacks the access needed to
unreflect the inherited public clone() method. The IllegalAccessException
is swallowed by DefaultGroovyMethodsSupport.cloneObject's catch-all and
cloneSimilarCollection falls back to LinkedHashSet, so

    EnumSet.of(A, B, C) + D

now returns a LinkedHashSet instead of an EnumSet. Subsequent assignment
to an EnumSet-typed variable or field then fails with a GroovyCastException.

Fall back to plain reflective Method.invoke when the MethodHandle Lookup
cannot access clazz. The clone method itself is public, so reflective
invocation succeeds without needing --add-opens.
@paulk-asert paulk-asert merged commit 7ab97ea into apache:GROOVY_4_0_X May 30, 2026
38 of 39 checks passed
@paulk-asert paulk-asert deleted the GROOVY-12020 branch May 30, 2026 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant