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)

Reply via email to