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

lambda proxy fails to access a protected member inherited from a split package

    XMLWordPrintable

    Details

    • Subcomponent:
    • Introduced In Build:
      b20
    • Introduced In Version:
      15
    • Resolved In Build:
      b23
    • CPU:
      x86_64
    • OS:
      windows_10
    • Verification:
      Not verified

      Description

      ADDITIONAL SYSTEM INFORMATION :
      openjdk version "15" 2020-09-15
      OpenJDK Runtime Environment AdoptOpenJDK (build 15+36)
      OpenJDK 64-Bit Server VM AdoptOpenJDK (build 15+36, mixed mode, sharing)

      A DESCRIPTION OF THE PROBLEM :
      If B inherits from A, and the two classes are loaded by different class loaders, and both are from unnamed modules.

      When B converts a protected method in A to lambda, the lambda will encounter IllegalAccessError when called.
      See the recurrence example for more details.

      PS: I originally found this issue in IntelliJ IDEA, which is a pretty serious problem.

      java.lang.IllegalAccessError: class com.intellij.openapi.roots.ui.configuration.ContentEntriesEditor$$Lambda$5009/0x00000008025e1c68 tried to access protected method 'void com.intellij.openapi.roots.ui.configuration.ModuleElementsEditor.fireConfigurationChanged()' (com.intellij.openapi.roots.ui.configuration.ContentEntriesEditor$$Lambda$5009/0x00000008025e1c68 is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader @5fe0e8fb; com.intellij.openapi.roots.ui.configuration.ModuleElementsEditor is in unnamed module of loader com.intellij.util.lang.UrlClassLoader @4f47d241)


      REGRESSION : Last worked in version 14.0.2

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run example: java Test.java

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Nothing
      ACTUAL -
      IllegalAccessError

      ---------- BEGIN SOURCE ----------
      import java.io.ByteArrayOutputStream;
      import java.io.IOException;
      import java.lang.invoke.MethodHandle;
      import java.lang.invoke.MethodHandles;
      import java.lang.invoke.MethodType;
      import java.net.URL;
      import java.net.URLClassLoader;

      public class Test {
          
          public static class A { protected void func() { } }
          
          public static class B extends A { public Runnable get() { return this::func; } }
          
      public static void main(String... args) throws Throwable {
      final URL empty[] = { };
      final class Loader extends URLClassLoader {

      private final Class<?> responsibility;

      public Loader(final ClassLoader parent, final Class<?> responsibility) {
      super(empty, parent);
      this.responsibility = responsibility;
      }

      @Override
      protected Class<?> findClass(final String name) throws ClassNotFoundException {
      try {
      if (name.equals(responsibility.getName())) {
      final byte[] bytes = getBytesFromClass(responsibility);
      return defineClass(null, bytes, 0, bytes.length);
      }
      } catch (IOException e) { throw new RuntimeException(e); }
      return super.findClass(name);
      }

      }
      final ClassLoader a = new Loader(null, A.class), b = new Loader(a, B.class);
      final Class<?> bClass = b.loadClass(B.class.getName());
      final MethodHandle get = MethodHandles.lookup().findVirtual(bClass, "get", MethodType.methodType(Runnable.class));
      final Runnable runnable = (Runnable) get.invoke(bClass.getDeclaredConstructor().newInstance());
      runnable.run();
      }

      private static byte[] getBytesFromClass(final Class<?> clazz) throws IOException {
      try (final var input = clazz.getClassLoader().getResourceAsStream(clazz.getName().replace('.', '/') + ".class")) {
      final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
      int nRead;
      final byte[] data = new byte[1 << 12];
      while ((nRead = input.read(data, 0, data.length)) != -1)
      buffer.write(data, 0, nRead);
      buffer.flush();
      return buffer.toByteArray();
      }
      }

      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Back to Java14

      FREQUENCY : always


        Attachments

          Issue Links

            Activity

              People

              Assignee:
              mchung Mandy Chung
              Reporter:
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: