James Daugherty created GROOVY-12553:
----------------------------------------

             Summary: @Log: a log call in a subclass is not guarded when the 
superclass with its own @Log is already compiled
                 Key: GROOVY-12553
                 URL: https://issues.apache.org/jira/browse/GROOVY-12553
             Project: Groovy
          Issue Type: Bug
          Components: AST Transforms
    Affects Versions: 4.0.33, 5.1.3
            Reporter: James Daugherty


{{@Log}}, {{@Slf4j}} and the other logging annotations wrap a log call whose 
arguments are not trivial in a level check, so {{log.fine('value: ' + value)}} 
compiles as {{if (log.isLoggable(Level.FINE)) log.fine('value: ' + value)}}. 
When the class extends another class with a logging annotation, the guard is 
only added while the superclass is compiled together with it. When the 
superclass is already compiled, the call is left unguarded, so its arguments 
are evaluated whatever the level, and the same source compiles to a different 
class file depending on what else is compiled.

{code:groovy}
@groovy.util.logging.Log
abstract class Base {
    void start() { log.info('starting ' + getClass().simpleName) }
}

@groovy.util.logging.Log
class Sub extends Base {
    void run(Object value) {
        log.fine('value: ' + value) // not guarded when Base is already compiled
    }
}
{code}

Reproduced with 4.0.33, 5.1.3 and master. A reproducer with a groovyc script 
and an incremental Gradle build: 
https://github.com/jdaugherty/groovy-log-guard-precompiled-superclass

*Cause*

{{LogASTTransformation}} adds the guard only when the {{log}} variable of the 
call is still a {{DynamicVariable}}, unbound because the log field is added by 
the transformation itself. With the superclass read from bytecode, the 
reference has already been bound to the superclass's own private {{log}} field, 
so the call is left unguarded. The transformation already accepts such a 
private field when it adds the subclass's log field.

*Proposed fix*

Treat a reference bound to a private field of another class the same as an 
unbound one.

Found while making incremental builds of a Grails application produce the same 
classes as a full build; see also GROOVY-12550 and GROOVY-12544.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to