Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8270056: Generated lambda class can not access protected static metho…
…d of target class

Reviewed-by: mchung
Backport-of: 07e90524576f159fc16523430f1db62327c89a3b
  • Loading branch information
Yi Yang committed Jul 14, 2021
1 parent 8583aab commit 0f5470715e98e222474f575abc95457682d5818a
@@ -187,7 +187,7 @@ public InnerClassLambdaMetafactory(MethodHandles.Lookup caller,
// 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 @@ void generate(MethodType methodType) {
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 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 static void splitPackage() throws Throwable {
((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 void test() {
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();
}
}
}

1 comment on commit 0f54707

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on 0f54707 Jul 14, 2021

Please sign in to comment.