{"record":{"id":"0fd17467ebc761b3","repo":"quarkusio/quarkus","slug":"non-static-public-field-field-present-on-normal","errorCode":null,"errorMessage":"Non-static public field ${field} present on normal scoped bean ${beanClass}","messagePattern":"Non-static public field (.+?) present on normal scoped bean (.+?)","errorType":"exception","errorClass":"DefinitionException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java","lineNumber":1357,"sourceCode":"        for (ClassInfo beanClass : beanClasses) {\n            BeanInfo classBean = Beans.createClassBean(beanClass, this, injectionPointTransformer);\n            if (classBean != null) {\n                beans.add(classBean);\n                beanClassToBean.put(beanClass, classBean);\n                injectionPoints.addAll(classBean.getAllInjectionPoints());\n\n                // specification requires to disallow non-static public fields on non-`@Dependent` beans,\n                // but we do what Weld does: only disallow them on normal scoped beans (disallowing them\n                // on `@Singleton` beans would actually prevent passing the AtInject TCK)\n                //\n                // only check this in the strictly compatible mode, as this is pretty invasive,\n                // it even prevents public producer fields\n                if (classBean.getScope().isNormal() && strictCompatibility) {\n                    ClassInfo aClass = beanClass;\n                    while (aClass != null) {\n                        for (FieldInfo field : aClass.fields()) {\n                            if (Modifier.isPublic(field.flags()) && !Modifier.isStatic(field.flags())) {\n                                throw new DefinitionException(\"Non-static public field \" + field\n                                        + \" present on normal scoped bean \" + beanClass);\n                            }\n                        }\n\n                        DotName superClass = aClass.superName();\n                        aClass = superClass != null && !superClass.equals(DotNames.OBJECT)\n                                ? getClassByName(getBeanArchiveIndex(), superClass)\n                                : null;\n                    }\n                }\n            }\n        }\n\n        List<DisposerInfo> disposers = new ArrayList<>();\n        for (MethodInfo disposerMethod : disposerMethods) {\n            BeanInfo declaringBean = beanClassToBean.get(disposerMethod.declaringClass());\n            if (declaringBean != null) {\n                Injection injection = Injection.forDisposer(disposerMethod, declaringBean.getImplClazz(), this,","sourceCodeStart":1339,"sourceCodeEnd":1375,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java#L1339-L1375","documentation":"With strict CDI compatibility enabled, normal-scoped beans (e.g. @ApplicationScoped) must not declare non-static public fields, because the client proxy would bypass field access semantics. ArC throws this DefinitionException while validating class beans.","triggerScenarios":"strictCompatibility is on and a class bean with a normal scope has a public non-static field (checked across the whole superclass hierarchy up to Object).","commonSituations":"Porting an existing CDI/Weld codebase where public fields were tolerated; writing structs/DTO-style beans with @ApplicationScoped; enabling quarkus.arc.strict-compatibility and newly failing existing beans.","solutions":["Make the field private and add getter/setter accessors.","Change the bean scope to @Dependent (pseudo-scope) if proxies are not needed.","Make the field static if it is genuinely constant-like.","Move the public fields into a separate non-bean POJO."],"exampleFix":"// before\n@ApplicationScoped\nclass Counter {\n  public int count;\n}\n// after\n@ApplicationScoped\nclass Counter {\n  private int count;\n  public int getCount() { return count; }\n}","handlingStrategy":"validation","validationCode":"// Check a normal-scoped bean class for public non-static fields\nstatic List<Field> offendingFields(Class<?> bean) {\n    List<Field> bad = new ArrayList<>();\n    for (Class<?> c = bean; c != null && c != Object.class; c = c.getSuperclass()) {\n        for (Field f : c.getDeclaredFields()) {\n            if (Modifier.isPublic(f.getModifiers()) && !Modifier.isStatic(f.getModifiers())) bad.add(f);\n        }\n    }\n    return bad;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use private fields with accessor methods in scoped beans","Avoid enabling strict-compatibility on legacy code without an audit","Use @Dependent scope for field-exposed DTO-style beans"],"tags":["cdi","quarkus-arc","strict-compatibility","public-field","normal-scope"],"backgroundTag":"public-field-on-normal-scoped-bean","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}