The CDI class BeanManager has several methods which take parameters of type Annotation or Annotation.... For example BeanManager.getBeans(...).
I would like to know how I'm supposed to pass my annotations as parameters to those methods.
I've tried BeanManager.getBeans(MyBean.class, MyAnnotation.class), but it doesn't work that way. I've seen Class.isAnnotation(), but there's nothing like Class.asAnnotation() to retrieve it as an Annotation type.
Neither BeanManager.getBeans(MyBean.class, #MyAnnotation) worked, nor did BeanManager.getBeans(MyBean.class, (Annotation) MyAnnotation.class).
How can I retrieve my annotation class as type Annotation?
There is an example in the documentation:
beanManager.getBeans(Object.class, new AnnotationLiteral<Any>() {});
Source: 16.6. The Bean interface
You need to use
getAnnotation(Class annotationClass) Returns this element's
annotation for the specified type if such an annotation is present,
else null.
Or loop through
getAnnotations() Returns all annotations present on this element.
To get the annotation.
object.getClass().getAnnotations()
javadoc
Related
I'm attempting to change the default type value for kafka listener with property "spring.json.value.default.type=" using my own annotation in spring-kafka. Currently, it's possible to overwrite it with following values:
properties="spring.json.value.default.type=com.package.class" which is canonical name of class.
I've made an annotation that sets the following value:
#MyAnnotation(topic = Topics.BUILD_CONFIG_CREATED, defaultType = ConstantsClass.TYPE_HEADER + "prz.student.finger.kafkaBSC.MyObjectDTO")
Is there any way to avoid hard typing the class name?
I would like to implement the option to use the following code(just giving the class that was imported):
#MyAnnotation(topic = Topics.BUILD_CONFIG_CREATED, defaultType = MyObjectDTO.class)
The closest to I've got is adding in my annotation:
#AliasFor(annotation = KafkaListener.class, attribute = "properties")
String defaultType() default headerType()+dtoType().getCanonicalName().toString();
String headerType() default "spring.json.value.default.type=";
Unfortunately, the constraints regarding the compilation time values for class in annotation blocks me from implementing it. Is there any way to inject the cannonical name without hard typing it, or any other way to implement this?
The properties property can contain SpEL (see its Javadocs).
Something like #{#someBean.type.name}; where someBean is a bean with a method public Class<?> getType().
I want to verity two dates parameters in a class, start day must before end day. However, I have multiple classes which have this demand, so I want to customize a generic annotation.
what I have tried:
class dataValidator<T : Any>: ConstraintValidator<DateConstraint, T>
It raised a error:
javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'my.test.annotation.DateValid' validating type 'my.test.model.DateModel'. Check configuration for ''
However, if I change my validator to this, and it works
class dataValidator<T : Any>: ConstraintValidator<DateConstraint, DateModel>
So, is there any way I can write a generic annotation?
Normally this problem will happen when you are trying to use incorrect validator annotation on any bean property, you must use the right annotations for the right types.
You can find more information here
I'm trying to get a Class object reference for the annotation which caused a ConstraintViolation in the javax.validation package (Apache Bval implementation).
After getting some ConstraintViolations, I pass them into the following function:
private Class<?> getConstraintAnnotation(final ConstraintViolation<?> constraintViolation) {
return constraintViolation
.getConstraintDescriptor()
.getAnnotation()
.getClass();
}
And this returns a class object whose getName(), getCanonicalName(), and getTypeName() all return "java.lang.reflect.Proxy".
Weirdly enough, the toString() method of the Class object returns back
"class com.sun.proxy.$Proxy10".
Is there a way for me to get the real annotation classes and not these proxies? I would ideally like to map the built-in annotations to error codes (without having to overwrite the message every time I use it).
Java annotation is implemented by Proxy. The Proxy do be the really annotation. You should use Annotation.annotationType rather than Object.getClass to get the real annotation class.
what will be correct Java annotation values in place of following?
#interface Demo
{
Class obj();
String class_name();
}
...
...
#Demo(obj=Class.forName("Example"),class_name=obj.getName())
i'm getting error as "annotation value must be a class literal"
Annotations must be constant at compile time. Therefore, methods are not allowed.
The above annotation can be done with this:
#Demo(obj=Example.class, class_name="Example")
Values passed to annotations must be known in compile-time, so you cannot use calls like Class.forName. Instead, you could use the class directly:
#Demo(obj = Example.class, class_name="com.exmaple.Example")
I have interface Resource and several classes implementing it, for example Audio, Video... Further, I have created custom annotation MyAnnotation with Class type param:
#MyAnnotation(type = Audio.class)
class Audio {
...
}
#MyAnnotation(type = Video.class)
class Video{
...
}
In some other place in code I have to use Interface Resource as a returned type:
public class Operations<T extends Resource> {
....
#OtherAnnotation(type = Audio.class (if audio), type = Video.class (if video) )
T getResource();
....
}
The question is how to appropriatelly annotate annotation #OtherAnnotation depending of what kind of Resource type will be returned ?
What you are asking is for dynamic values for annotation attributes.
However annotations can only be set at compile time which is the reason why their values can only be compile time constants. You may only read them at runtime.
There was a similar question in which someone tried to generate the annotation value , it's answer explains why there is no way to dynamically generate a value used in annotation in a bit more detail. In that question there was an attempt to use a final class variable generated with a static method.
There are annotation processors which offer a bit more flexibility by handling placeholders. However i don't think this fits your case, as you want the dynamic values at runtime.
This answer refers to spring's use of the expression language for the Value annotation in which the placeholder (#Value("#{systemProperties.dbName})") gets overrided with the data from one of the property sources defined ( example in spring boot )
In any case, you will have to rethink your architecture a bit.