Mattias Reichel created GROOVY-12257:
----------------------------------------
Summary: Groovy 4 @Immutable bytecode fails on Groovy 5 because
ObjectUtil was removed
Key: GROOVY-12257
URL: https://issues.apache.org/jira/browse/GROOVY-12257
Project: Groovy
Issue Type: Bug
Affects Versions: 5.0.8
Reporter: Mattias Reichel
h3. Summary
A class compiled with Groovy 4 using @Immutable fails at runtime when executed
with Groovy 5.
The Groovy 4 @Immutable AST transformation generates bytecode that calls:
{code:java}
org.apache.groovy.runtime.ObjectUtil.cloneObject(Object)
{code}
org.apache.groovy.runtime.ObjectUtil is present in Groovy 4 but was removed in
Groovy 5. Constructing an affected class therefore throws:
{code:java}
java.lang.NoClassDefFoundError: org/apache/groovy/runtime/ObjectUtil
{code}
h3. Reproducer
A minimal Gradle reproducer is provided here:
https://github.com/matrei/groovy-immutable-compat. It compiles the class with
Groovy 4.0.33 and runs it with Groovy 5.0.8:
{code:groovy}
import groovy.transform.Immutable
@Immutable
class ImmutableValue {
List<String> values
}
println new ImmutableValue(['value'])
{code}
Run:
{code:bash}
./gradlew reproduce
{code}
h3. Actual Behaviour
Compilation succeeds with Groovy 4, but execution with Groovy 5 fails when the
immutable class is instantiated:
{code:java}
java.lang.NoClassDefFoundError: org/apache/groovy/runtime/ObjectUtil
{code}
h3. Expected Behaviour
Groovy 4-compiled @Immutable classes should remain binary-compatible with
Groovy 5, or the Groovy 5 transformation/runtime should provide a compatibility
path for the generated bytecode.
Recompiling the source with Groovy 5 avoids the problem, but this does not help
users consuming libraries or plugins distributed as Groovy 4-compiled binaries.
h3. Root Cause
The Groovy 4 @Immutable transformation emits calls to
ObjectUtil.cloneObject(Object) for defensive copying of properties such as
collections. The referenced runtime class was removed in Groovy 5:
{code:java}
Groovy 4: org/apache/groovy/runtime/ObjectUtil.class is present
Groovy 5: org/apache/groovy/runtime/ObjectUtil.class is absent
{code}
The failure is not detected during dependency resolution or application
startup. It occurs only when the affected immutable class is instantiated.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)