[ 
https://issues.apache.org/jira/browse/GROOVY-11126?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17745127#comment-17745127
 ] 

Jochen Theodorou edited comment on GROOVY-11126 at 7/20/23 3:18 PM:
--------------------------------------------------------------------

[~emilles]I think that needs a bit rework. First of all I would change the test 
to not do the times loop, it is not required for the issue, and if it is, then 
the there is another problem hidden by your solution. So I suggest using:
{code:Java}
           def test(String string) {
                string?.size()
            }

            test('1')
            test('')
            test()
            test('2')
{code}
that is especially to cover the case NotNull->Null and Null->NotNull. 

New line 943 does the null case, and applies guards IS_NULL and optionally 
SAME_CLASS. 964 is the elseif to that, so here the receiver is not null. It 
adds here the SAME_CLASS check if the arguments can change class. Your new code 
in 970 is then another elseif and only called if the receiver is not null and 
the arguments cannnot change class. Which means it will not be added in the 
following case:
{code:Java}
           def test(string) {
                string?.size()
            }

            test('1')
            test('')
            test()
            test('2')
{code} 
Therefore your if-block should be inside the first elseif.

Unless I did misread the code again of course.


was (Author: blackdrag):
[~emilles]I think that needs a bit rework. First of all I would change the test 
to not do the times loop, it is not required for the issue, and if it is, then 
the there is another problem hidden by your solution. So I suggest using:
{code:Java}
           def test(String string) {
                string?.size()
            }

            test('1')
            test('')
            test()
            test('2')
{code:Java}
that is especially to cover the case NotNull->Null and Null->NotNull. 

New line 943 does the null case, and applies guards IS_NULL and optionally 
SAME_CLASS. 964 is the elseif to that, so here the receiver is not null. It 
adds here the SAME_CLASS check if the arguments can change class. Your new code 
in 970 is then another elseif and only called if the receiver is not null and 
the arguments cannnot change class. Which means it will not be added in the 
following case:
{code:Java}
           def test(string) {
                string?.size()
            }

            test('1')
            test('')
            test()
            test('2')
{code:Java} 
Therefore your if-block should be inside the first elseif.

Unless I did misread the code again of course.

> Null-safe Dereference fails after time
> --------------------------------------
>
>                 Key: GROOVY-11126
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11126
>             Project: Groovy
>          Issue Type: Bug
>          Components: bytecode
>    Affects Versions: 4.0.11, 4.0.12
>         Environment: Zulu Java 17.0.7, Amazon Linux 2023, Spring Boot 3.1.1
>            Reporter: Kenneth W DeLong
>            Assignee: Eric Milles
>            Priority: Critical
>             Fix For: 4.0.14
>
>         Attachments: javapOutput.txt, javapOutput2.txt
>
>
> I have a server-side app that works perfectly for a long time (18-24h) then 
> suddenly starts throwing "impossible" errors.
> {code:java}
> Caused by: java.lang.NullPointerException: Cannot invoke 
> "java.lang.CharSequence.length()" because "self" is null     
>         at 
> org.codehaus.groovy.runtime.StringGroovyMethods.size(StringGroovyMethods.java:2693)
>         at org.codehaus.groovy.runtime.dgm$1323.doMethodInvoke(Unknown Source)
>       at 
> com.hatchbaby.model.ColorParser.isOneByteFormat(ColorParser.groovy:74)
>       at com.hatchbaby.model.ColorParser.getRed(ColorParser.groovy:13)
>       at com.hatchbaby.domain.Content.getRed(Content.groovy:173)
>  {code}
> The line of code at ColorParser:74 is:
> {code:java}
> int size = color?.size() ?: 0 {code}
> The variable `color` is a String. The null-safe dereference operator has 
> ceased to short-circuit.
> This code is years old and has run flawlessly. Since the upgrade from Spring 
> Boot 2.7.4 to Boot 3.1.1, it runs fine for 18-24h, then it starts throwing 
> NullPointerExceptions.  This is happening at a couple of other places in the 
> code, all on null-safe dereferences that don't short-circuit. The above code 
> is hit 9,000+ times/day. We have a cluster of servers and they seem to 
> develop the problem within a couple hours of each other.
> The server is running with Spring Boot 3.1.1 (hence Groovy 4.0.12) running on 
> Java 17.0.7 (Azul Zulu) on Amazon Linux 2023. The project is joint Java and 
> Groovy code that is compiled with the GMavenPlus 3.0.0 Maven plugin (maven 
> 3.9.1)
> I have tried to reproduce the error by running a tiny program that mimics the 
> error, but so far after running 1.4 million invocations over 24h with no 
> errors (as you might expect).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to