Citrus Registry and Resource Injection
@BindToRegistry issues
This inspection reports various issues when using the @BindToRegistry annotation
Non-public methods
According to the @BindToRegistry Citrus documentation, The annotation works with public methods…, thus this inspection, on one hand, reports non-public @BindToRegistry annotated methods. When a non-public method is encountered by Citrus, the test execution results in a failure with a message like this:
class com.consol.citrus.annotations.CitrusAnnotations cannot access a member of class [some fully qualified class name] with modifiers “private”

Void methods
It also reports @BindToRegistry methods with void return types, because that would result in null values assigned to the respective Citrus registry objects.

Fields without initializers
@BindToRegistry fields without initializers are reported too, because that would result in null values assigned to the respective Citrus registry objects.

Citrus resources injected into @CitrusTest methods without @CitrusResource
The Citrus documentation, for example the Test action runner injectionsection states that
The parameter requires the @CitrusResource annotations in order to mark the parameter for Citrus resource injection.
In order to make sure that injection happens, this inspection analyzes the parameters of @CitrusTest annotated test methods: if a parameter of type TestCaseRunner, TestActionRunner or TestContext is defined without the @CitrusResource annotation, it is marked as a violation.
Additionally, a quick fix available to add the @CitrusResource annotation to the selected parameter.

Convert @BindToRegistry field to method and vice versa
According to the Citrus documentation on the @BindToRegistry annotation, it can be placed on both fields and public methods, and they are interchangeable.
To make the conversion simpler between the two forms, there are two intention actions called Convert field to @BindToRegistry method and Convert method to @BindToRegistry field that can convert such fields to their corresponding method forms and back.
The intentions are available on the name of @BindToRegistry annotated fields and methods when those fields don’t have any other annotation on them. In case of converting methods to fields, the method must have a single return statement, in order for the intention to be available.
The conversions happen as follows:
- Field -> method:
- If the
@BindToRegistryannotation’snameattribute is set to a non-empty value, it is carried over tothe method as well, otherwise it isn’t. - The generated method is always public, as Citrus can access such methods only if they are public.
- The generated method’s name is always the original field’s name.
- The code block of the generated method is the field’s initializer as a
returnstatement, or empty if the field has no initializer.
- If the
- Method -> field:
- If the
@BindToRegistryannotation’snameattribute is set to a non-empty value, it is carried over to the field as well, otherwise it isn’t. - The generated field has the same visibility as the original method (regardless of that non-public @BindToRegistry methods are not valid).
- The generated field’s name is always the original method’s name.
- The initializer of the generated method is the method’s single
returnstatement.
- If the

Extract CitrusContext.bind() call to @BindToRegistry field and method
Using the @BindToRegistry annotation is an alternative to calling CitrusContext.bind(), thus this intention action extracts CitrusContext.bind() calls to their corresponding @BindToRegistry annotated field and method forms.
The intention is available:
- on the identifier of
CitrusContext.bind()calls, - when the value of the name argument can be evaluated to a string literal by the IntelliJ Platform.
The name attribute of @BindToRegistry is set in the following cases:
- either when the name value is a Java keyword,
- or when there is at least one character in the object name that is not allowed to be used in a Java identifier, i.e. in a field name.
If the object name is a Java keyword, the field/method name gets prefixed with an underscore. Whether the name is a Java keyword is determined by the JDK version used in the current module. It falls back to the project-level JDK, and then the highest language level, if no JDK is found.

Static code checks of resource injections
This inspection provides multiple checks regarding Citrus-injected resources, and reports the following:
- A field is annotated with
@CitrusFrameworkbut the field type is notCitrus. This would prevent injecting the Citrus object into the field.

- A field is annotated with
@CitrusEndpointbut the field type is notEndpointor one of its inheritors. This would prevent injecting anEndpointobject into the field.

- A field is annotated with one of the
@*EndpointConfig/@*ClientConfig/@*ServerConfigannotations, but it is not annotated with@CitrusEndpoint. This would prevent injecting anEndpointobject into the field, and then be able to override its properties.

- A field has as type one of the inheritors of
Endpointbut the@*EndpointConfig/@*ClientConfig/@*ServerConfigannotation on the field doesn’t match the type. E.g.:DirectEndpointfield annotated with@CamelEndpointConfig.
