GROOVY-8144: Invoking a public method declared in a non-public class result in a IllegalAccessError (closes #522)
Commit 1a4c9918a4f12e64 introduced the DecompiledClassNode as part of enabling the ASM class resolver. Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/a1fac74b Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/a1fac74b Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/a1fac74b Branch: refs/heads/parrot Commit: a1fac74b1d6b6d419fb97566b5da7829636099ee Parents: e06a1ea Author: John Wagenleitner <[email protected]> Authored: Sat Apr 15 07:59:29 2017 -0700 Committer: John Wagenleitner <[email protected]> Committed: Sat Apr 15 08:05:00 2017 -0700 ---------------------------------------------------------------------- .../classgen/asm/sc/StaticInvocationWriter.java | 5 +- src/test/groovy/bugs/Groovy8144Bug.groovy | 85 ++++++++++++++++++++ .../org/codehaus/groovy/dummy/Groovy8144A.java | 26 ++++++ .../codehaus/groovy/dummy/Groovy8144ABase.java | 25 ++++++ .../org/codehaus/groovy/dummy/Groovy8144B.java | 26 ++++++ .../codehaus/groovy/dummy/Groovy8144BBase.java | 23 ++++++ .../org/codehaus/groovy/dummy/Groovy8144C.java | 26 ++++++ .../codehaus/groovy/dummy/Groovy8144CBase.java | 23 ++++++ 8 files changed, 238 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/a1fac74b/src/main/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java b/src/main/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java index 09ca8ae..778d740 100644 --- a/src/main/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java +++ b/src/main/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java @@ -27,6 +27,7 @@ import org.codehaus.groovy.ast.GroovyCodeVisitor; import org.codehaus.groovy.ast.InnerClassNode; import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.Parameter; +import org.codehaus.groovy.ast.decompiled.DecompiledClassNode; import org.codehaus.groovy.ast.expr.*; import org.codehaus.groovy.ast.stmt.ExpressionStatement; import org.codehaus.groovy.ast.stmt.ForStatement; @@ -706,7 +707,9 @@ public class StaticInvocationWriter extends InvocationWriter { } else { type = getWrapper(controller.getTypeChooser().resolveType(receiver, controller.getClassNode())); ClassNode declaringClass = target.getDeclaringClass(); - if (type.getClass() != ClassNode.class && type.getClass() !=InnerClassNode.class) { + if (type.getClass() != ClassNode.class + && type.getClass() != InnerClassNode.class + && type.getClass() != DecompiledClassNode.class) { type = declaringClass; // ex: LUB type } if (OBJECT_TYPE.equals(type) && !OBJECT_TYPE.equals(declaringClass)) { http://git-wip-us.apache.org/repos/asf/groovy/blob/a1fac74b/src/test/groovy/bugs/Groovy8144Bug.groovy ---------------------------------------------------------------------- diff --git a/src/test/groovy/bugs/Groovy8144Bug.groovy b/src/test/groovy/bugs/Groovy8144Bug.groovy new file mode 100644 index 0000000..da7172c --- /dev/null +++ b/src/test/groovy/bugs/Groovy8144Bug.groovy @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package groovy.bugs + +import org.codehaus.groovy.classgen.asm.AbstractBytecodeTestCase +import org.codehaus.groovy.control.CompilerConfiguration +import org.codehaus.groovy.control.SourceUnit + +/** + * This test requires the test classes executed are compiled and on the + * classpath and not in the same compilation unit. + */ +class Groovy8144Bug extends AbstractBytecodeTestCase { + + GroovyShell shell + + protected Map<String, Boolean> getOptions() { + ['asmResolving': Boolean.TRUE] + } + + @Override + void setUp() { + CompilerConfiguration config = new CompilerConfiguration(CompilerConfiguration.DEFAULT) + config.optimizationOptions.putAll(getOptions()) + shell = new GroovyShell(config) + } + + void testMethodInheritedFromNonPublicAbstractBaseClass() { + checkAnswer('Groovy8144A') + } + + void testMethodInheritedFromPublicAbstractBaseClass() { + checkAnswer('Groovy8144B') + } + + void testMethodInheritedFromPublicBaseClass() { + checkAnswer('Groovy8144C') + } + + void checkAnswer(String testClassName) { + String code = """ + import org.codehaus.groovy.dummy.${testClassName} + + @groovy.transform.CompileStatic + def m() { + new ${testClassName}().answer() + } + + assert m() == 42 + """ + + def action = { SourceUnit unit -> + unit.getConfiguration().optimizationOptions.putAll(getOptions()) + } + + assert compile([conversionAction:action, method:'m'], code).hasSequence([ + "INVOKEVIRTUAL org/codehaus/groovy/dummy/${testClassName}.answer ()I" + ]) + + shell.evaluate(code) + } +} + +class Groovy8144BugAsmResolveOff extends Groovy8144Bug { + @Override + protected Map<String, Boolean> getOptions() { + ['asmResolving': Boolean.FALSE] + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/a1fac74b/src/test/org/codehaus/groovy/dummy/Groovy8144A.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/dummy/Groovy8144A.java b/src/test/org/codehaus/groovy/dummy/Groovy8144A.java new file mode 100644 index 0000000..cd6becb --- /dev/null +++ b/src/test/org/codehaus/groovy/dummy/Groovy8144A.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.dummy; + +/** + * Inherits a public method from a package-private base class and is used to verify + * the generated INVOKEVIRTUAL call is on this and not super. + */ +public class Groovy8144A extends Groovy8144ABase { +} http://git-wip-us.apache.org/repos/asf/groovy/blob/a1fac74b/src/test/org/codehaus/groovy/dummy/Groovy8144ABase.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/dummy/Groovy8144ABase.java b/src/test/org/codehaus/groovy/dummy/Groovy8144ABase.java new file mode 100644 index 0000000..f174c6d --- /dev/null +++ b/src/test/org/codehaus/groovy/dummy/Groovy8144ABase.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.dummy; + +abstract class Groovy8144ABase { + public int answer() { + return 42; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/a1fac74b/src/test/org/codehaus/groovy/dummy/Groovy8144B.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/dummy/Groovy8144B.java b/src/test/org/codehaus/groovy/dummy/Groovy8144B.java new file mode 100644 index 0000000..338cef6 --- /dev/null +++ b/src/test/org/codehaus/groovy/dummy/Groovy8144B.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.dummy; + +/** + * Inherits a public method from a public abstract base class and is used to verify + * the generated INVOKEVIRTUAL call is on this and not super. + */ +public class Groovy8144B extends Groovy8144BBase { +} http://git-wip-us.apache.org/repos/asf/groovy/blob/a1fac74b/src/test/org/codehaus/groovy/dummy/Groovy8144BBase.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/dummy/Groovy8144BBase.java b/src/test/org/codehaus/groovy/dummy/Groovy8144BBase.java new file mode 100644 index 0000000..d885049 --- /dev/null +++ b/src/test/org/codehaus/groovy/dummy/Groovy8144BBase.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.dummy; + +public abstract class Groovy8144BBase { + public int answer() { return 42; } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/a1fac74b/src/test/org/codehaus/groovy/dummy/Groovy8144C.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/dummy/Groovy8144C.java b/src/test/org/codehaus/groovy/dummy/Groovy8144C.java new file mode 100644 index 0000000..bf2f748 --- /dev/null +++ b/src/test/org/codehaus/groovy/dummy/Groovy8144C.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.dummy; + +/** + * Inherits a public method from a public base class and is used to verify + * the generated INVOKEVIRTUAL call is on this and not super. + */ +public class Groovy8144C extends Groovy8144CBase { +} http://git-wip-us.apache.org/repos/asf/groovy/blob/a1fac74b/src/test/org/codehaus/groovy/dummy/Groovy8144CBase.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/dummy/Groovy8144CBase.java b/src/test/org/codehaus/groovy/dummy/Groovy8144CBase.java new file mode 100644 index 0000000..dcc0171 --- /dev/null +++ b/src/test/org/codehaus/groovy/dummy/Groovy8144CBase.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.dummy; + +public class Groovy8144CBase { + public int answer() { return 42; } +}
