Skip to content
Permalink
Browse files
8270056: Generated lambda class can not access protected static metho…
…d of target class

Co-authored-by: NekoCaffeine <nekocaffeine@qq.com>
Reviewed-by: mchung
  • Loading branch information
Yi Yang and NekoCaffeine committed Jul 13, 2021
1 parent afe957c commit 07e90524576f159fc16523430f1db62327c89a3b
@@ -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();
}
}
}

7 comments on commit 07e9052

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot replied Jul 13, 2021

@kelthuzadx

This comment has been minimized.

Copy link
Member

@kelthuzadx kelthuzadx replied Jul 13, 2021

/backport jdk17

@openjdk

This comment has been minimized.

Copy link

@openjdk openjdk bot replied Jul 13, 2021

@kelthuzadx the backport was successfully created on the branch kelthuzadx-backport-07e90524 in my personal fork of openjdk/jdk17. To create a pull request with this backport targeting openjdk/jdk17:master, just click the following link:

➡️ Create pull request

The title of the pull request is automatically filled in correctly and below you find a suggestion for the pull request body:

Hi all,

this pull request contains a backport of commit 07e90524 from the openjdk/jdk repository.

The commit being backported was authored by Yi Yang on 13 Jul 2021 and was reviewed by Mandy Chung.

Thanks!

If you need to update the source branch of the pull then run the following commands in a local clone of your personal fork of openjdk/jdk17:

$ git fetch https://github.com/openjdk-bots/jdk17 kelthuzadx-backport-07e90524:kelthuzadx-backport-07e90524
$ git checkout kelthuzadx-backport-07e90524
# make changes
$ git add paths/to/changed/files
$ git commit --message 'Describe additional changes made'
$ git push https://github.com/openjdk-bots/jdk17 kelthuzadx-backport-07e90524
@kelthuzadx

This comment has been minimized.

Copy link
Member

@kelthuzadx kelthuzadx replied Jul 13, 2021

/backport jdk15u-dev

@openjdk

This comment has been minimized.

Copy link

@openjdk openjdk bot replied Jul 13, 2021

@kelthuzadx could not automatically backport 07e90524 to openjdk/jdk15u-dev due to conflicts in the following files:

  • src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
  • test/jdk/java/lang/invoke/lambda/superProtectedMethod/ProtectedMethodInOtherPackage.java

To manually resolve these conflicts run the following commands in your personal fork of openjdk/jdk15u-dev:

$ git checkout -b kelthuzadx-backport-07e90524
$ git fetch --no-tags https://git.openjdk.java.net/jdk 07e90524576f159fc16523430f1db62327c89a3b
$ git cherry-pick --no-commit 07e90524576f159fc16523430f1db62327c89a3b
$ # Resolve conflicts
$ git add files/with/resolved/conflicts
$ git commit -m 'Backport 07e90524576f159fc16523430f1db62327c89a3b'

Once you have resolved the conflicts as explained above continue with creating a pull request towards the openjdk/jdk15u-dev with the title Backport 07e90524576f159fc16523430f1db62327c89a3b.

@kelthuzadx

This comment has been minimized.

Copy link
Member

@kelthuzadx kelthuzadx replied Jul 13, 2021

/backport jdk16u

@openjdk

This comment has been minimized.

Copy link

@openjdk openjdk bot replied Jul 13, 2021

@kelthuzadx could not automatically backport 07e90524 to openjdk/jdk16u due to conflicts in the following files:

  • src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java

To manually resolve these conflicts run the following commands in your personal fork of openjdk/jdk16u:

$ git checkout -b kelthuzadx-backport-07e90524
$ git fetch --no-tags https://git.openjdk.java.net/jdk 07e90524576f159fc16523430f1db62327c89a3b
$ git cherry-pick --no-commit 07e90524576f159fc16523430f1db62327c89a3b
$ # Resolve conflicts
$ git add files/with/resolved/conflicts
$ git commit -m 'Backport 07e90524576f159fc16523430f1db62327c89a3b'

Once you have resolved the conflicts as explained above continue with creating a pull request towards the openjdk/jdk16u with the title Backport 07e90524576f159fc16523430f1db62327c89a3b.

Please sign in to comment.