{"id":"dc920afb5cae33fe","repo":"junit-team/junit5","slug":"annotationconsumerinstance-getclass-getname","errorCode":null,"errorMessage":"${annotationConsumerInstance.getClass().getName()} must be used with an annotation of type ${annotationType.getName()}","messagePattern":"(.+?) must be used with an annotation of type (.+?)","errorType":"exception","errorClass":"JUnitException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-params/src/main/java/org/junit/jupiter/params/support/AnnotationConsumerInitializer.java","lineNumber":61,"sourceCode":"\t\tnew MethodSignature(\"provideArguments\", 2, 1), //\n\t\tnew MethodSignature(\"convert\", 3, 2));\n\n\tprivate static final Predicate<Method> consumesAnnotation = methodSignatures.stream() //\n\t\t\t.map(signature -> (Predicate<Method>) signature::matches) //\n\t\t\t.reduce(method -> false, Predicate::or);\n\n\tprivate AnnotationConsumerInitializer() {\n\t\t/* no-op */\n\t}\n\n\t@SuppressWarnings({ \"unchecked\", \"rawtypes\" })\n\tpublic static <T> T initialize(AnnotatedElement annotatedElement, T annotationConsumerInstance) {\n\t\tif (annotationConsumerInstance instanceof AnnotationConsumer consumer) {\n\t\t\tClass<? extends Annotation> annotationType = findConsumedAnnotationType(annotationConsumerInstance);\n\t\t\tList<? extends Annotation> annotations = findAnnotations(annotatedElement, annotationType);\n\n\t\t\tif (annotations.isEmpty()) {\n\t\t\t\tthrow new JUnitException(annotationConsumerInstance.getClass().getName()\n\t\t\t\t\t\t+ \" must be used with an annotation of type \" + annotationType.getName());\n\t\t\t}\n\n\t\t\tannotations.forEach(annotation -> initializeAnnotationConsumer(consumer, annotation));\n\t\t}\n\t\treturn annotationConsumerInstance;\n\t}\n\n\tprivate static <T extends Annotation> List<T> findAnnotations(AnnotatedElement annotatedElement,\n\t\t\tClass<T> annotationType) {\n\n\t\treturn annotationType.isAnnotationPresent(Repeatable.class)\n\t\t\t\t? findRepeatableAnnotations(annotatedElement, annotationType)\n\t\t\t\t: findAnnotation(annotatedElement, annotationType).map(Collections::singletonList).orElse(emptyList());\n\t}\n\n\tprivate static <T> Class<? extends Annotation> findConsumedAnnotationType(T annotationConsumerInstance) {\n\t\tMethod method = findMethods(annotationConsumerInstance.getClass(), consumesAnnotation, BOTTOM_UP).get(0);","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/junit-team/junit5/blob/956246301e03d757539f7b76dd5a91f298637563/junit-jupiter-params/src/main/java/org/junit/jupiter/params/support/AnnotationConsumerInitializer.java#L43-L79","documentation":"AnnotationConsumerInitializer.initialize looks for annotations of the type its target consumes on the annotated element; if none are found it throws JUnitException. A custom provider/converter that implements AnnotationConsumer<A> was registered (e.g. via @ArgumentsSource) but the matching annotation A is not present on the test class/method.","triggerScenarios":"Registering `@ArgumentsSource(MyProvider.class)` where MyProvider implements AnnotationConsumer<MyAnnotation>, but the @ParameterizedTest element is missing @MyAnnotation (or it is on the wrong target / non-retained).","commonSituations":"Authoring a custom source annotation and forgetting to put it on the test; @Target mismatch; annotation not annotated with @Retention(RUNTIME); meta-annotation not picked up across element types.","solutions":["Add the consumed annotation to the @ParameterizedTest method or @ParameterizedClass.","Ensure the annotation declares @Retention(RUNTIME) and an appropriate @Target.","If the provider should be self-contained, register the annotation as a meta-annotation on @ArgumentsSource or use @ArgumentsSource as the carrier."],"exampleFix":"// before\n@ParameterizedTest\n@ArgumentsSource(MyProvider.class)   // MyProvider consumes @MyAnno\nvoid test(int x) { }\n\n// after\n@ParameterizedTest\n@MyAnno(\"x\")\n@ArgumentsSource(MyProvider.class)\nvoid test(int x) { }","handlingStrategy":"validation","validationCode":"// Ensure the consumed annotation is actually present on the element.\njava.lang.reflect.AnnotatedElement el = method;\nClass<? extends java.lang.annotation.Annotation> consumed = MyAnno.class;\nif (el.getAnnotation(consumed) == null\n        && el.getDeclaredAnnotationsByType(consumed).length == 0) {\n    throw new IllegalStateException(\"Missing @\" + consumed.getSimpleName()\n        + \" required by the registered provider\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    // run the parameterized test\n} catch (JUnitException e) {\n    if (e.getMessage().contains(\"must be used with an annotation of type\")) {\n        // add the expected annotation to the test element\n    } else throw e;\n}","preventionTips":["Keep custom source annotations on the same element as @ArgumentsSource.","Give custom annotations @Retention(RUNTIME) and a fitting @Target.","Document, on the provider, which annotation it consumes."],"tags":["junit","jupiter-params","annotation-consumer","configuration"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}