You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Daniel Sun (Jira)" <ji...@apache.org> on 2019/12/21 18:43:00 UTC

[jira] [Updated] (GROOVY-9352) Static compilation fails with NoClassDefFoundError

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

Daniel Sun updated GROOVY-9352:
-------------------------------
    Fix Version/s: 3.0.0-rc-3
                   2.5.9

> Static compilation fails with NoClassDefFoundError
> --------------------------------------------------
>
>                 Key: GROOVY-9352
>                 URL: https://issues.apache.org/jira/browse/GROOVY-9352
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static compilation
>    Affects Versions: 2.5.8, 3.0.0-rc-2
>            Reporter: Cédric Champeau
>            Priority: Major
>             Fix For: 2.5.9, 3.0.0-rc-3
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> The static compiler is trying to resolve classes which it shouldn't. Imagine the following scenario:
>  
>  * a project written in Java exposes class `A` which has a private method using `D` as a parameter
>  * `D` is an _implementation_ dependency of `A`, meaning it's not exposed in its public API, so consumers of `A` should never require `D` to build against `A`
>  * a project `B` written in Groovy consumes `A` and tries to call a _public_ method of `A`
>  ** if the class is using `@CompileStatic`, compilation FAILS with a NoClassDefFoundError
>  ** if the class doesn't use `@CompileStatic`, compilation passes as expected
> The reason is that when we compile `B`, we only put on the compile classpath the _API_ dependencies of `A`. But Groovy breaks because when it inspects class `A`, it tries to load internal implementation details (private fields, methods) and as such fails.
> This is a big problem because it effectively breaks the contract of API/implementation separation, and forces either the producer to declare `D` as an _implementation_ dependency, which it's not, or redeclare `D` as an implementation dependency of `B`, which it isn't either, just to make the compiler happy!
>  
> The Gradle build itself is suffering from this. This is not nice because it forces compilation of things we don't need, and forces us to redeclare dependencies that we shouldn't.
>  
> To reproduce, checkout this project: [https://github.com/melix/groovy-compiler-bug]
>  
> and run `./gradlew build`
>  



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