This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch GROOVY-10198 in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 616e0302df19e2bfc3b88494faa6d973885412bf Author: Eric Milles <[email protected]> AuthorDate: Fri Nov 28 19:12:33 2025 -0600 GROOVY-10198: ignore pickMethod result if private or package-private --- src/main/java/groovy/lang/MetaClassImpl.java | 6 +++- src/test/groovy/bugs/Groovy10198.groovy | 51 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java index 7306845de8..a334b1236a 100644 --- a/src/main/java/groovy/lang/MetaClassImpl.java +++ b/src/main/java/groovy/lang/MetaClassImpl.java @@ -3708,13 +3708,17 @@ out: if (metaClass instanceof MetaClassImpl metaClassImpl) { protected static MetaMethod findOwnMethod(Class instanceKlazz, String methodName, Class[] arguments, MetaClass metaClass, MetaMethod method) { if (instanceKlazz != metaClass.getTheClass()) { MetaMethod ownMethod = metaClass.pickMethod(methodName, arguments); - if (ownMethod != null) { + if (ownMethod != null && !isPrivate(ownMethod, instanceKlazz)) { // GROOVY-10198 method = (method == null ? ownMethod : mostSpecific(method, ownMethod, instanceKlazz)); } } return method; } + private static boolean isPrivate(MetaMethod method, Class instanceKlazz) { + return method.isPrivate() || (method.isPackagePrivate() && !inSamePackage(method.getDeclaringClass().getTheClass(), instanceKlazz)); + } + protected Object getSubclassMetaMethods(String methodName) { return null; } diff --git a/src/test/groovy/bugs/Groovy10198.groovy b/src/test/groovy/bugs/Groovy10198.groovy new file mode 100644 index 0000000000..66d74fb12f --- /dev/null +++ b/src/test/groovy/bugs/Groovy10198.groovy @@ -0,0 +1,51 @@ +/* + * 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 bugs + +import org.junit.jupiter.api.Test + +import static groovy.test.GroovyAssert.shouldFail + +final class Groovy10198 { + + @Test + void testMetaClassChangeKeepsPrivate() { + def pogo = new Two() + shouldFail(MissingMethodException) { + def value = pogo.getValue() + } + One.metaClass.getThing << { -> 'thing' } + try { + shouldFail(MissingMethodException) { + def value = pogo.getValue() + } + } finally { + One.metaClass = null + } + } + + static class One { + private String getValue() { + 'something private' + } + } + + static class Two extends One { + } +}
