[
https://issues.apache.org/jira/browse/GROOVY-12516?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Scott Murphy Heiberg updated GROOVY-12516:
------------------------------------------
Description:
Under {{@CompileStatic}}, a call to {{super.m()}} inside a closure or lambda is
compiled to a call to a generated method {{super$2$m}} in the enclosing class.
When two closures or lambdas of the same class call the same super method, the
method is generated twice and the class cannot be loaded:
{code:groovy}
class Base { String m() { 'base' } }
@groovy.transform.CompileStatic
class Sub extends Base {
String m() { 'sub' }
List<String> test() {
def a = { -> super.m() }
def b = { -> super.m() }
[a(), b()]
}
}
new Sub().test()
{code}
{code}
java.lang.ClassFormatError: Duplicate method name "super$2$m" with signature
"()Ljava.lang.String;" in class file Sub
{code}
Dynamic Groovy and {{@TypeChecked}} return {{base, base}}. With only one of the
two closures calling {{super.m()}}, {{@CompileStatic}} works. The same happens
with two lambdas, or a closure and a lambda. Seen in 4.0.33 (reported there as
"General error during instruction selection"), 5.0.8, 6.0.0 and master.
Expected: one {{super$2$m}} method, shared by all the calls.
PR: https://github.com/apache/groovy/pull/3044
was:
Under {{@CompileStatic}}, a call to {{super.m()}} inside a closure or lambda is
compiled to a call to a generated method {{super$2$m}} in the enclosing class.
When two closures or lambdas of the same class call the same super method, the
method is generated twice and the class cannot be loaded:
{code:groovy}
class Base { String m() { 'base' } }
@groovy.transform.CompileStatic
class Sub extends Base {
String m() { 'sub' }
List<String> test() {
def a = { -> super.m() }
def b = { -> super.m() }
[a(), b()]
}
}
new Sub().test()
{code}
{code}
java.lang.ClassFormatError: Duplicate method name "super$2$m" with signature
"()Ljava.lang.String;" in class file Sub
{code}
Dynamic Groovy and {{@TypeChecked}} return {{base, base}}. With only one of the
two closures calling {{super.m()}}, {{@CompileStatic}} works. The same happens
with two lambdas, or a closure and a lambda. Seen in 4.0.33 (reported there as
"General error during instruction selection"), 5.0.8, 6.0.0 and master.
Expected: one {{super$2$m}} method, shared by all the calls.
> SC: two closures calling the same super method produce a duplicate super$
> method (ClassFormatError)
> ---------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12516
> URL: https://issues.apache.org/jira/browse/GROOVY-12516
> Project: Groovy
> Issue Type: Bug
> Components: Static compilation
> Affects Versions: 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> Under {{@CompileStatic}}, a call to {{super.m()}} inside a closure or lambda
> is compiled to a call to a generated method {{super$2$m}} in the enclosing
> class. When two closures or lambdas of the same class call the same super
> method, the method is generated twice and the class cannot be loaded:
> {code:groovy}
> class Base { String m() { 'base' } }
> @groovy.transform.CompileStatic
> class Sub extends Base {
> String m() { 'sub' }
> List<String> test() {
> def a = { -> super.m() }
> def b = { -> super.m() }
> [a(), b()]
> }
> }
> new Sub().test()
> {code}
> {code}
> java.lang.ClassFormatError: Duplicate method name "super$2$m" with signature
> "()Ljava.lang.String;" in class file Sub
> {code}
> Dynamic Groovy and {{@TypeChecked}} return {{base, base}}. With only one of
> the two closures calling {{super.m()}}, {{@CompileStatic}} works. The same
> happens with two lambdas, or a closure and a lambda. Seen in 4.0.33 (reported
> there as "General error during instruction selection"), 5.0.8, 6.0.0 and
> master.
> Expected: one {{super$2$m}} method, shared by all the calls.
> PR: https://github.com/apache/groovy/pull/3044
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)