[ 
https://issues.apache.org/jira/browse/GROOVY-9916?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Eric Milles updated GROOVY-9916:
--------------------------------
    Fix Version/s: 3.0.8

> IllegalArgumentException when set null to a boolean field into a closure
> ------------------------------------------------------------------------
>
>                 Key: GROOVY-9916
>                 URL: https://issues.apache.org/jira/browse/GROOVY-9916
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.5.13, 3.0.7
>            Reporter: Eric Vernier
>            Assignee: Eric Milles
>            Priority: Critical
>             Fix For: 3.0.8, 4.0.0-alpha-3
>
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> The following exception has been thrown by an application in production:
> {code}
> Caused by: java.lang.IllegalArgumentException: Can not set boolean field 
> c.c.a.a.b.t.b.save.RestoreDataMssqlTask.schemaExistInBackup to null value
>       at 
> sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
>       at 
> sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
>       at 
> sun.reflect.UnsafeBooleanFieldAccessorImpl.set(UnsafeBooleanFieldAccessorImpl.java:80)
>       at java.lang.reflect.Field.set(Field.java:764)
>       at 
> org.codehaus.groovy.reflection.CachedField.setProperty(CachedField.java:76)
>       at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2718)
>       at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3809)
>       at 
> c.c.a.a.b.t.b.save.AbstractRestoreTask.setProperty(AbstractRestoreTask.groovy)
>       at 
> org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:213)
>       at groovy.lang.Closure.setPropertyTryThese(Closure.java:370)
>       at groovy.lang.Closure.setPropertyOwnerFirst(Closure.java:364)
>       at groovy.lang.Closure.setProperty(Closure.java:353)
>       at 
> org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setGroovyObjectProperty(ScriptBytecodeAdapter.java:544)
>       at 
> c.c.a.a.b.t.b.save.RestoreDataMssqlTask$_execImportDatasource_closure1.doCall(RestoreDataMssqlTask.groovy:86)
> {code}
> I think the following test class reproduces the problem :
> {code:groovy}
> class Test {
>       private boolean b
>       
>       static final void main(String... args) {
>               new Test().f()
>       }
>       
>       def f() {
>               println('set boolean to null')
>               b = null
>               def closure = { 
>                       println('set boolean to null inside a closure')
>                       b = null
>               }
>               closure()
>       }       
> }
> {code}
> The conditions are 1) affect null to a primitive boolean variable, 2) the 
> variable must be an instance field, 3) the affectation must be executed in a 
> closure
> With Groovy 2.5.5 no exception.
> {code}
> $ groovy -version
> Groovy Version: 2.5.5 JVM: 1.8.0_265 Vendor: AdoptOpenJDK OS: Windows 10
> $ groovy Test
> set boolean to null
> set boolean to null inside a closure
> {code}
> But with groovy 2.5.13 or the last stable version 3.0.7 the second 
> affectation failed :
> {code}
> $ groovy -version
> Groovy Version: 3.0.7 JVM: 1.8.0_265 Vendor: AdoptOpenJDK OS: Windows 10
> $ groovy Test
> set boolean to null
> set boolean to null inside a closure
> Caught: java.lang.IllegalArgumentException: Can not set boolean field Test.b 
> to null value
> java.lang.IllegalArgumentException: Can not set boolean field Test.b to null 
> value
>         at Test$_f_closure1.doCall(Test.groovy:14)
>         at Test$_f_closure1.doCall(Test.groovy)
>         at Test.f(Test.groovy:16)
>         at Test$f.call(Unknown Source)
>         at Test.main(Test.groovy:6)
> {code}
> In {{org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation}} the 
> method 
> [castToBoolean()|https://github.com/apache/groovy/blob/ac852d6a53bcb583849cb8db8a1cbede5b097502/src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java#L185]
>  takes care of the {{null}} value in accordance with the Groovy truth:
> {code:java}
> public static boolean castToBoolean(Object object) {
>         // null is always false
>         if (object == null) {
>             return false;
>         }
> {code}
> but the method {{castToBoolean()}} is obviously  never called by 
> [castToType()|https://github.com/apache/groovy/blob/ac852d6a53bcb583849cb8db8a1cbede5b097502/src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java#L218]
>  when the value is null because the first line of castToType is :
> {code:java}
> if (object == null) return null;
> {code}
> How can I deal with this behaviour? I guess I must stuck ith the old 2.5.5 ?



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to