Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-7233

Configurable @Log AST logger field access modifiers

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • None
    • 3.0.0-alpha-4
    • None

    Description

      On rare occasions, it can be desirable for a logger to be non-private.

      Consider a @Log-annotated class with a method containing anonymous closures that log using the class's AST-injected logger.

      BaseClient.groovy
      @Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1' )
      import groovy.util.logging.*
      import groovyx.net.http.*
      import static groovyx.net.http.ContentType.*
      import static groovyx.net.http.Method.*
      
      @Log
      class BaseClient {
          def fetchDocuments(String id) {
              new HTTPBuilder('https://tsdrapi.uspto.gov').request(GET, XML) {
                  log.fine "Retrieving documents for case $id..."
                  uri.path = "/ts/cd/casedocs/$id/info.xml"
                  response.success = { resp, xml ->
                      log.fine "..successfully received data for $id"
                      xml
                  }
              }
          }
      }
      

      Invoking new BaseClient().fetchDocuments('86375968') works as expected. However, if a subclass is written that invokes the parent method, such as:

      Client.groovy
      class Client extends BaseClient {
          def getDocuments() {
              fetchDocuments('86375968')
          }
      }
      

      Invoking new Client().documents surprisingly results in a groovy.lang.MissingPropertyException: No such property: log for class: groovyx.net.http.HTTPBuilder$RequestConfigDelegate error. I believe this is due to the closure delegation being done via the subclass, which does not have visibility to the parent class's private fields--namely, the injected log field.

      Other than a design change, or by defining a new log variable within the parent method (def log = log, this problem can be avoided if the log field had protected visibility.

      Here's an example of how it would look.

      @Log(access='protected')
      class SomeClass {}
      

      results in

      public class SomeClass {
          protected static transient final Logger log;
      }
      

      Attachments

        Issue Links

          Activity

            People

              paulk Paul King
              bdkosher Joe Wolf
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 0.5h
                  0.5h