JDK-8233837 : getConstructor() not working as expected
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 11
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2019-11-08
  • Updated: 2019-11-14
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
Windows 10, OpenJDK 11.0.2


A DESCRIPTION OF THE PROBLEM :
getConstructor() throws 'NoSuchMethodException <init>()' with default inner and outer and also private inner classes with default-constructors.
These classes can be instantiated by normal new aswell with the depracted Class#newInstance() method but not with Class#getConstructor#newInstance().


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
to test you can use the provides sourcecode


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
all of the examples should work without error

ACTUAL -
--- ni.problem.NewInstanceProblem$PublicInnerClass
  -> normal instantiation  -> created
  -> Class.forName()
  -> newInstance()  -> created
  -> getConstructor()  -> newInstance()  -> created
--- ni.problem.NewInstanceProblem$DefaultInnerClass
  -> normal instantiation  -> created
  -> Class.forName()
  -> newInstance()  -> created
  -> getConstructor()
java.lang.NoSuchMethodException: ni.problem.NewInstanceProblem$DefaultInnerClass.<init>()
        at java.base/java.lang.Class.getConstructor0(Class.java:3350)
        at java.base/java.lang.Class.getConstructor(Class.java:2152)
        at ni.problem.NewInstanceProblem.create(NewInstanceProblem.java:47)
        at ni.problem.NewInstanceProblem.main(NewInstanceProblem.java:65)
--- ni.problem.NewInstanceProblem$PrivateInnerClass
  -> normal instantiation  -> created
  -> Class.forName()
  -> newInstance()  -> created
  -> getConstructor()
java.lang.NoSuchMethodException: ni.problem.NewInstanceProblem$PrivateInnerClass.<init>()
        at java.base/java.lang.Class.getConstructor0(Class.java:3350)
        at java.base/java.lang.Class.getConstructor(Class.java:2152)
        at ni.problem.NewInstanceProblem.create(NewInstanceProblem.java:47)
        at ni.problem.NewInstanceProblem.main(NewInstanceProblem.java:67)
--- ni.problem.PublicOuterClass
  -> normal instantiation  -> created
  -> Class.forName()
  -> newInstance()  -> created
  -> getConstructor()  -> newInstance()  -> created
--- ni.problem.DefaultOuterClass
  -> normal instantiation  -> created
  -> Class.forName()
  -> newInstance()  -> created
  -> getConstructor()
java.lang.NoSuchMethodException: ni.problem.DefaultOuterClass.<init>()
        at java.base/java.lang.Class.getConstructor0(Class.java:3350)
        at java.base/java.lang.Class.getConstructor(Class.java:2152)
        at ni.problem.NewInstanceProblem.create(NewInstanceProblem.java:47)
        at ni.problem.NewInstanceProblem.main(NewInstanceProblem.java:70)



---------- BEGIN SOURCE ----------
--- source for NewInstanceProblem:
package ni.problem;

import java.lang.reflect.Constructor;
import java.util.function.Supplier;

public class NewInstanceProblem {

  public static class PublicInnerClass {
    //
  }

  static class DefaultInnerClass {
    //
  }

  private static class PrivateInnerClass {
    //
  }

  private static void create(final String clazzName,
    final Supplier<Object> doNew) {

    System.out.printf("--- %s%n", clazzName);

    try {
      System.out.printf("  -> normal instantiation", clazzName);
      doNew.get();
      System.out.printf("  -> created%n");
    } catch (final Exception e) {
      System.out.printf("%n");
      e.printStackTrace(System.out);
    }

    try {
      System.out.printf("  -> Class.forName()%n", clazzName);
      final Class<?> c = Class.forName(clazzName);
      try {
        System.out.printf("  -> newInstance()", clazzName);
        c.newInstance();
        System.out.printf("  -> created%n");
      } catch (final Exception e) {
        System.out.printf("%n");
        e.printStackTrace(System.out);
      }
      try {
        System.out.printf("  -> getConstructor()", clazzName);
        final Constructor<?> cx = c.getConstructor();
        System.out.printf("  -> newInstance()", clazzName);
        final Object o = cx.newInstance();
        System.out.printf("  -> created%n");
      } catch (final Exception e) {
        System.out.printf("%n");
        e.printStackTrace(System.out);
      }
    } catch (final Exception e) {
      System.out.printf("%n");
      e.printStackTrace(System.out);
    }

  }

  public static void main(final String[] args) {
    create("ni.problem.NewInstanceProblem$PublicInnerClass",
      () -> new PublicInnerClass());
    create("ni.problem.NewInstanceProblem$DefaultInnerClass",
      () -> new DefaultInnerClass());
    create("ni.problem.NewInstanceProblem$PrivateInnerClass",
      () -> new PrivateInnerClass());
    create("ni.problem.PublicOuterClass", () -> new PublicOuterClass());
    create("ni.problem.DefaultOuterClass", () -> new DefaultOuterClass());
  }

}

--- source for PublicOuterClass:
package ni.problem;

public class PublicOuterClass {
  //
}

--- source for DefaultOuterClass:
package ni.problem;

class DefaultOuterClass {
  //
}


---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
use deprecated newInstance() instead of recommended getConstructor().newInstance()


FREQUENCY : always