{"record":{"id":"49352a7a537900f1","repo":"quarkusio/quarkus","slug":"method-s-of-class-s-is-annotated-with-s-an","errorCode":null,"errorMessage":"Method '%s' of class '%s' is annotated with @%s annotation which is prohibited. Classes used as @BeanParam parameters must have a JAX-RS parameter annotation on fields only.","messagePattern":"Method '(.+?)' of class '(.+?)' is annotated with @(.+?) annotation which is prohibited\\. Classes used as @BeanParam parameters must have a JAX-RS parameter annotation on fields only\\.","errorType":"validation","errorClass":"DeploymentException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java","lineNumber":670,"sourceCode":"            return new PeriodParamConverter.Supplier();\n        }\n\n        throw new RuntimeException(\n                contextualizeErrorMessage(\"Unable to handle temporal type '\" + paramType + \"'\", currentMethodInfo));\n    }\n\n    private void validateMethodsForInjectableBean(ClassInfo currentClassInfo) {\n        // do not check methods of records, they get the annotations from their record components, but that's automatic:\n        // they are actually placed on the constructor parameters and also end up on the fields and methods\n        if (currentClassInfo.isRecord()) {\n            return;\n        }\n        for (MethodInfo method : currentClassInfo.methods()) {\n            for (AnnotationInstance annotation : method.annotations()) {\n                if (annotation.target().kind() == AnnotationTarget.Kind.METHOD) {\n                    for (DotName annotationForField : JAX_RS_ANNOTATIONS_FOR_FIELDS) {\n                        if (annotation.name().equals(annotationForField)) {\n                            throw new DeploymentException(String.format(\n                                    \"Method '%s' of class '%s' is annotated with @%s annotation which is prohibited. \"\n                                            + \"Classes used as @BeanParam parameters must have a JAX-RS parameter annotation on \"\n                                            + \"fields only.\",\n                                    method.name(), currentClassInfo.name().toString(),\n                                    annotation.name().withoutPackagePrefix()));\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private String contextualizeErrorMessage(String errorMessage, MethodInfo currentMethodInfo) {\n        errorMessage += \". Offending method if '\" + currentMethodInfo.name() + \"' of class '\"\n                + currentMethodInfo.declaringClass().name() + \"'\";\n        return errorMessage;\n    }\n","sourceCodeStart":652,"sourceCodeEnd":688,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/ServerEndpointIndexer.java#L652-L688","documentation":"RESTEasy Reactive's ServerEndpointIndexer validates classes used as @BeanParam parameters during deployment. JAX-RS requires that @BeanParam classes carry JAX-RS parameter annotations (@QueryParam, @HeaderParam, etc.) on their FIELDS only; placing such an annotation on a method is prohibited, so the build step throws a DeploymentException and the application fails to start.","triggerScenarios":"A class used as a @BeanParam resource method parameter has a JAX-RS field annotation (e.g. @QueryParam, @PathParam, @HeaderParam, @CookieParam, @MatrixParam, @FormParam, @Context) placed on a setter or other method instead of (or in addition to) a field, and the class is not a record.","commonSituations":"Migrating legacy JAX-RS code that used annotated setters for property injection; code generated by IDEs that create getters/setters copying annotations; refactoring a @BeanParam class where annotations were accidentally moved from fields to methods.","solutions":["Move the JAX-RS parameter annotation from the method to the corresponding field in the @BeanParam class","If annotated setters are used, annotate the field directly and leave the setter unannotated","If the class is a record, annotations on components are handled automatically - consider converting to a record","Remove any duplicate method-level JAX-RS parameter annotations"],"exampleFix":"// before\nclass MyParams {\n  private String name;\n  @QueryParam(\"name\")\n  public void setName(String name) { this.name = name; }\n}\n// after\nclass MyParams {\n  @QueryParam(\"name\")\n  private String name;\n  public void setName(String name) { this.name = name; }\n}","handlingStrategy":"validation","validationCode":"// Check all @BeanParam classes for JAX-RS annotations on methods\nfor (Class<?> beanParam : beanParamClasses) {\n  for (Method m : beanParam.getDeclaredMethods()) {\n    for (Annotation a : m.getAnnotations()) {\n      String n = a.annotationType().getName();\n      if (n.startsWith(\"jakarta.ws.rs.\") && (n.contains(\"Param\") || n.equals(\"jakarta.ws.rs.core.Context\")))\n        throw new IllegalStateException(beanParam.getName() + \" has \" + n + \" on method \" + m.getName());\n    }\n  }\n}","typeGuard":"boolean isValidBeanParam(Class<?> c) {\n  return java.util.Arrays.stream(c.getDeclaredMethods())\n    .flatMap(m -> java.util.Arrays.stream(m.getAnnotations()))\n    .noneMatch(a -> a.annotationType().getName().matches(\"jakarta\\\\.ws\\\\.rs\\\\..*(Param|Context)\"));\n}","tryCatchPattern":null,"preventionTips":["Always place @QueryParam/@PathParam/@HeaderParam etc. on fields of @BeanParam classes","Never rely on annotated setters for JAX-RS property injection","Review @BeanParam classes after IDE auto-generation of getters/setters","Prefer records for simple @BeanParam data carriers"],"tags":["quarkus","resteasy-reactive","beanparam","deployment-time"],"backgroundTag":"beanparam-invalid-annotation-placement","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}