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/10/25 15:04:00 UTC

[jira] [Assigned] (GROOVY-8145) Cross-project @Log + static import issue

     [ https://issues.apache.org/jira/browse/GROOVY-8145?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Eric Milles reassigned GROOVY-8145:
-----------------------------------

    Assignee: Eric Milles

> Cross-project @Log + static import issue
> ----------------------------------------
>
>                 Key: GROOVY-8145
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8145
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler, Static compilation
>    Affects Versions: 2.4.10
>            Reporter: M. Justin
>            Assignee: Eric Milles
>            Priority: Major
>
> I have discovered a situation in which doing a static import of all members of a class causes a compilation error as the compiler incorrectly infers that the code is attempting to use a private static member on the imported class.
> There appears to be a very specific combination of factors that causes this to occur.  Specifically, the class that's doing the static import must be statically compiled using the {{@CompileStatic}} annotation, and both classes must share a logger variable with the same name from {{@Log}} (or {{@Slf4j}}, etc.).  Furthermore, the classes cannot be compiled at the same time (for instance, the one could be in a jar or a sub-build in Gradle).
> The following is a specific Gradle example that produces the issue.
> First, the build structure:
> {noformat}
> import-static-issue
>   src/main/groovy/test
>     build.gradle
>     settings.gradle
>     Importer.groovy
>     SameProjectImported.groovy
>   subproject
>     src/main/groovy/test/DifferentProjectImported.groovy
> {noformat}
> And the relevant files:
> {code:title=build.gradle}
> group 'test'
> version '1.0-SNAPSHOT'
> allprojects {
>   apply plugin: 'groovy'
>   apply plugin: 'java'
>   sourceCompatibility = 1.8
>   repositories {
>     mavenCentral()
>   }
>   dependencies {
>     compile 'org.codehaus.groovy:groovy-all:2.4.10'
>   }
> }
> dependencies {
>   compile project(':subproject')
> }
> {code}
> {code:title=settings.gradle}
> include 'subproject'
> {code}
> {code:title=Importer.groovy}
> package test
> import groovy.transform.CompileStatic
> import groovy.util.logging.Log
> //import static test.SameProjectImported.* //Using this one instead won't trigger the issue
> import static test.DifferentProjectImported.*
> @Log
> @CompileStatic
> class Importer {
>   static void main(String[] args) {
>     log.info 'This will cause a compilation failure'
>   }
> }
> {code}
> {code:title=SameProjectImported.groovy}
> package test
> import groovy.util.logging.Log
> @Log
> class SameProjectImported {
> }
> {code}
> {code:title=DifferentProjectImported.groovy}
> package test
> import groovy.util.logging.Log
> @Log
> class DifferentProjectImported {
>   // private static java.util.logging.Logger log // Using this instead of @Log will also cause the error
> }
> {code}
> Compiling this code via Gradle (e.g. "gradle compileGroovy") produces the following error:
> {noformat}/[...]/import-static-issue/src/main/groovy/test/Importer.groovy: -1: Access to test.DifferentProjectImported#log is forbidden @ line -1, column -1.{noformat}
> I have confirmed the issue in Groovy 2.4.10.  I have also confirmed that this issue appears to have been present for the whole Groovy 2.x series.
> It doesn't occur if you manually create the private static field in the importing class instead of using the {{@Log}} AST transformation.  It will occur if you manually create the static "log" field in the statically imported class but use {{@Log}} in the importing class.  It doesn't occur if the importing class doesn't use {{@CompileStatic}}.  It doesn't occur if the importing class and the imported class are in the same Gradle project.  The issue also occurs if you statically import just the "log" field and not "*" (though practically speaking, you should never actually try to do that).
> I ran across this issue when I was migrating some code into a shared library and was statically importing a number of fields for a class that was being moved.  Manually declaring the fields to be statically imported would work, but my IDE settings would fold it back into "*" if the imports are ever optimized for the class, so this isn't a workable solution for me (if nothing else, it would be supremely confusing for any developers down the road).
> Edit: Upon further investigation, there is a different but related issue if the importing class is not annotated with {{@CompileStatic}}.  If it's not statically compiled, rather than throwing a compilation failure, it will instead use the imported private log variable, not its own.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)