ppkarwasz commented on issue #2769: URL: https://github.com/apache/logging-log4j2/issues/2769#issuecomment-2454228124
Hi @jaykataria1111, > not sure if I could find any other way of finding setters looking at the reflection API The usage of the Reflection API suggests to me that you want to do this check at **runtime**, right? I would rather do this check in our [`PluginProcessor`](https://github.com/apache/logging-log4j2/blob/2.x/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessor.java) class, which is used during the compilation process and provides access to more advanced APIs (like the language model in the [`javax.lang.model.element`](https://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/package-summary.html) package. **Note**: If you never wrote an annotation processor, its API has a steep learning curve, but the feature only requires a small part of this API: 1. You need to add [`PluginBuilderAttribute`](https://logging.apache.org/log4j/2.x/javadoc/log4j-core/org/apache/logging/log4j/core/config/plugins/PluginBuilderAttribute.html) to the list of annotations handled by `PluginProcessor`. 2. You can easily recover all the Java language [`Element`](https://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/Element.html)s using the [`RoundEnvironment`](https://docs.oracle.com/javase/8/docs/api/javax/annotation/processing/RoundEnvironment.html): ```java roundEnv.getElementsAnnotatedWith(PluginBuilderAttribute.class); ``` 3. The annotated elements should be of type [`VariableElement`](https://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/VariableElement.html) (which corresponds to fields and method parameters). You can then loop through all the methods (`ExecutableElement`) in the containing class to see if a setter is defined: ```java private void processBuilderAttributes(final VariableElement element) { final String fieldName = element.getSimpleName().toString(); final Element enclosingElement = element.getEnclosingElement(); // `element is a field if (enclosingElement instanceof TypeElement) { final TypeElement typeElement = (TypeElement) enclosingElement; // Check the siblings of the field for (final Element enclosedElement : typeElement.getEnclosedElements()) { if (enclosedElement instanceof ExecutableElement) { final ExecutableElement methodElement = (ExecutableElement) enclosedElement; final String methodName = methodElement.getSimpleName().toString(); if (methodName.startsWith("set") && methodElement.getParameters().size() == 1) { // Check if this is the right setter and if it matches return } } } // If the setter wan not found generate a compiler error. processingEnv.getMessager().printMessage( Diagnostic.Kind.ERROR, String.format("The field `%s` does not have a setter", fieldName), element ); } } ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
