Details
-
Improvement
-
Status: Closed
-
Minor
-
Resolution: Fixed
-
None
-
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.
@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:
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
- links to