You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (Jira)" <ji...@apache.org> on 2021/03/03 03:16:00 UTC
[jira] [Updated] (GROOVY-9916) IllegalArgumentException when set
null to a boolean field into a closure
[ 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)