Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8290417

CDS cannot archive lamda proxy with useImplMethodHandle

    XMLWordPrintable

Details

    • b32

    Backports

      Description

        See Test.java from the attachment for the reproduction steps:

        $ java17 -showversion -cp test.jar -XX:ArchiveClassesAtExit=test.jsa \
          -Djdk.internal.lambda.dumpProxyClasses=DUMP_CLASS_FILES \
          -Xlog:cds Test

        $ java17 -showversion -cp test.jar -XX:SharedArchiveFile=test.jsa -Xlog:cds Test
        [....]
        java version "17" 2021-09-14 LTS
        Java(TM) SE Runtime Environment (build 17+35-LTS-2724)
        Java HotSpot(TM) 64-Bit Server VM (build 17+35-LTS-2724, mixed mode, sharing)
        Exception in thread "main" java.lang.NullPointerException
        at java.base/java.util.Optional.ifPresent(Optional.java:178)
        at Tester.test(Unknown Source)
        at Test.main(Unknown Source)

        =========================================
        Note that the generated lambd proxy class used "ldc ... Dynamic" for getting a MethodHandle to Base::provideDownstreamSubscription, because the target method is a protected method in a different package. While this method is accessible from Tester (it's from a super type of Tester), it's not accessible from the lambda proxy class.

        See here for more info: https://github.com/openjdk/jdk/blob/522b65743ca10fcba0a27d25b8fa11319999e228/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java#L183-L191

        $ find DUMP_CLASS_FILES | grep Tester
        DUMP_CLASS_FILES/Tester$$Lambda$1.class
        $ javap -c -private 'DUMP_CLASS_FILES/Tester$$Lambda$1.class'
        final class Tester$$Lambda$1 implements java.util.function.Consumer {
          private final Tester arg$1;

          private Tester$$Lambda$1(Tester);
            Code:
               0: aload_0
               1: invokespecial #13 // Method java/lang/Object."<init>":()V
               4: aload_0
               5: aload_1
               6: putfield #15 // Field arg$1:LTester;
               9: return

          public void accept(java.lang.Object);
            Code:
               0: ldc #28 // Dynamic #0:_:Ljava/lang/invoke/MethodHandle;
               2: aload_0
               3: getfield #15 // Field arg$1:LTester;
               6: aload_1
               7: checkcast #30 // class java/lang/String
              10: invokevirtual #36 // Method java/lang/invoke/MethodHandle.invokeExact:(LTester;Ljava/lang/String;)V
              13: return
        }

        Attachments

          1. Base.java
            0.1 kB
          2. test.jar
            2 kB
          3. Test.java
            0.9 kB

          Issue Links

            Activity

              People

                iklam Ioi Lam
                iklam Ioi Lam
                Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: