8270056: Generated lambda class can not access protected static method of target class

Co-authored-by: NekoCaffeine <nekocaffeine@qq.com>
Reviewed-by: mchung
This commit is contained in:
Yi Yang 2021-07-13 02:24:14 +00:00
parent afe957cd97
commit 07e9052457
2 changed files with 45 additions and 5 deletions
src/java.base/share/classes/java/lang/invoke
test/jdk/java/lang/invoke/lambda/superProtectedMethod

@ -187,7 +187,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
// to invoke directly. (javac prefers to avoid this situation by
// generating bridges in the target class)
useImplMethodHandle = (Modifier.isProtected(implInfo.getModifiers()) &&
!VerifyAccess.isSamePackage(implClass, implInfo.getDeclaringClass())) ||
!VerifyAccess.isSamePackage(targetClass, implInfo.getDeclaringClass())) ||
implKind == H_INVOKESPECIAL;
cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
int parameterCount = factoryType.parameterCount();
@ -564,7 +564,10 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
convertArgumentTypes(methodType);
if (useImplMethodHandle) {
MethodType mtype = implInfo.getMethodType().insertParameterTypes(0, implClass);
MethodType mtype = implInfo.getMethodType();
if (implKind != MethodHandleInfo.REF_invokeStatic) {
mtype = mtype.insertParameterTypes(0, implClass);
}
visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle",
"invokeExact", mtype.descriptorString(), false);
} else {

@ -23,8 +23,8 @@
/*
* @test
* @bug 8227415 8254975
* @run testng/othervm p.SuperMethodTest
* @bug 8227415 8254975 8270056
* @run testng/othervm p.ProtectedMethodInOtherPackage
* @summary method reference to a protected method inherited from its
* superclass in a different runtime package where
* lambda proxy class has no access to it.
@ -50,7 +50,7 @@ import java.util.function.Function;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
public class SuperMethodTest {
public class ProtectedMethodInOtherPackage {
@Test
public static void remotePackageSameLoader() {
Sub_I sub = new Sub_I();
@ -101,6 +101,30 @@ public class SuperMethodTest {
((Runnable) get.invoke(b)).run();
}
@Test
public static void protectedStaticMethodInSplitPackage() throws Throwable {
ClassLoader parent = new Loader("loader-A1", null, A1.class);
ClassLoader loader = new Loader("loader-B1", parent, B1.class);
Class<?> aClass1 = Class.forName(A1.class.getName(), false, loader);
Class<?> bClass1 = Class.forName(B1.class.getName(), false, loader);
assertTrue(aClass1.getClassLoader() == parent);
assertTrue(bClass1.getClassLoader() == loader);
assertEquals(aClass1.getPackageName(), bClass1.getPackageName());
// verify subclass can access a static protected method inherited from
// its superclass in a split package
MethodHandle test = MethodHandles.lookup()
.findStatic(bClass1, "test", MethodType.methodType(void.class));
test.invoke();
// verify lambda can access a static protected method inherited from
// a superclass of the host class where the superclass is in
// a split package (not the same runtime package as the host class)
MethodHandle get = MethodHandles.lookup()
.findStatic(bClass1, "get", MethodType.methodType(Runnable.class));
((Runnable) get.invoke()).run();
}
static class Loader extends URLClassLoader {
static final Path CLASSES_DIR = Paths.get(System.getProperty("test.class.path"));
private final Class<?> c;
@ -138,4 +162,17 @@ public class SuperMethodTest {
func();
}
}
public static class A1 {
protected static void func() { }
}
public static class B1 extends A1 {
public static Runnable get() {
return A1::func;
}
public static void test() {
func();
}
}
}