{"record":{"id":"bbb521d296b891cf","repo":"google/gson","slug":"unable-to-invoke-no-args-constructor-of-rawtype","errorCode":null,"errorMessage":"Unable to invoke no-args constructor of ${rawType}; constructor is not accessible and ReflectionAccessFilter does not permit making it accessible. Register an InstanceCreator or a TypeAdapter for this type, change the visibility of the constructor or adjust the access filter.","messagePattern":"Unable to invoke no-args constructor of (.+?); constructor is not accessible and ReflectionAccessFilter does not permit making it accessible\\. Register an InstanceCreator or a TypeAdapter for this type, change the visibility of the constructor or adjust the access filter\\.","errorType":"exception","errorClass":"JsonIOException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java","lineNumber":424,"sourceCode":"   * ObjectConstructor}, which would then choose another way of creating the object. And it supports\n   * types which are only serialized but not deserialized (compared to directly throwing an\n   * exception when the {@code ObjectConstructor} is requested), e.g. when the runtime type of an\n   * object is inaccessible, but the compile-time type is accessible.\n   */\n  private static final class ThrowingObjectConstructor<T> implements ObjectConstructor<T> {\n    private final String exceptionMessage;\n\n    ThrowingObjectConstructor(String exceptionMessage) {\n      this.exceptionMessage = exceptionMessage;\n    }\n\n    @Override\n    public T construct() {\n      // New exception is created every time to avoid keeping a reference to an exception with\n      // potentially long stack trace, causing a memory leak\n      // (which would happen if the exception was already created when the\n      // `ThrowingObjectConstructor` is created)\n      throw new JsonIOException(exceptionMessage);\n    }\n  }\n\n  private static final class InstanceCreatorConstructor<T> implements ObjectConstructor<T> {\n    private final InstanceCreator<T> instanceCreator;\n    private final Type type;\n\n    InstanceCreatorConstructor(InstanceCreator<T> instanceCreator, Type type) {\n      this.instanceCreator = instanceCreator;\n      this.type = type;\n    }\n\n    @Override\n    public T construct() {\n      return instanceCreator.createInstance(type);\n    }\n  }\n}","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java#L406-L442","documentation":"Thrown when a no-args constructor exists but is not accessible (private/protected/package-private) and the ReflectionAccessFilter does not permit making it accessible (BLOCK_INACCESSIBLE or BLOCK_ALL). The filter prevents the setAccessible(true) call that Gson would otherwise use.","triggerScenarios":"A class has a non-public no-args constructor; a ReflectionAccessFilter with BLOCK_INACCESSIBLE or BLOCK_ALL is registered for the type; the canAccess check fails or the filter blocks the accessibility escalation.","commonSituations":"Java 9+ JPMS modules where the package isn't open to Gson; private constructors with strict reflection filters; using the built-in BLOCK_INACCESSIBLE_JAVA filter; library classes with package-private constructors.","solutions":["Change the no-args constructor visibility to public so no setAccessible is needed","Register an InstanceCreator for the type to bypass reflective construction","Adjust the ReflectionAccessFilter to ALLOW the specific type","Add a module 'opens' directive so Gson can access the package"],"exampleFix":"// before\nclass Foo { private Foo() {} }\n// + filter returning BLOCK_INACCESSIBLE\n\n// after\nclass Foo { public Foo() {} }","handlingStrategy":"validation","validationCode":"// Check constructor accessibility given the active filter\nConstructor<?> ctor = MyType.class.getDeclaredConstructor();\nFilterResult result = myFilter.check(MyType.class);\nboolean accessibleByDefault = ReflectionAccessFilterHelper.canAccess(ctor, null);\nif (!accessibleByDefault && result != FilterResult.ALLOW) {\n  throw new IllegalStateException(\n    MyType + \" no-args ctor inaccessible and filter is \" + result + \"; make ctor public or register InstanceCreator\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  return gson.fromJson(json, MyType.class);\n} catch (JsonIOException e) {\n  if (e.getMessage().startsWith(\"Unable to invoke no-args constructor\") && e.getMessage().contains(\"not accessible\")) {\n    // make ctor public, widen filter, or register InstanceCreator\n    throw new MyParseException(\"Constructor inaccessible for \" + MyType.class, e);\n  }\n  throw e;\n}","preventionTips":["Make no-args constructors public on classes you want Gson to deserialize, so setAccessible isn't needed","If you use BLOCK_INACCESSIBLE filters, register InstanceCreators for types with non-public constructors","Add module 'opens' directives for packages Gson needs to access under JPMS","Test on the target JDK with the same module/filter configuration as production"],"tags":["reflection-filter","accessibility","constructor","jpms","security"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}