Reputation: 1716
I want to read class level annotations using core java. I tried this:
Annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Fix {
public String[] author() default "";
}
Class:
@Fix(author="John Doe")
public class TestClass {
public void test(){
}
}
Test method to read the class:
ResourcePatternResolver resolversec = new PathMatchingResourcePatternResolver();
Resource[] resour = resolversec.getResources("classpath*:/com/validation/*.class");
Class<?> cl = resolversec.getClassLoader().loadClass("com.validation.ValidateCharacteristicsProcessor");
if(cl != null){
out.println("Class is not null " + cl.getSimpleName());
}
Fix fix = cl.getAnnotation(Fix.class);
if (fix != null) {
out.println("!!!! " + fix.author());
}
But the annotation @Fix
is coming empty. Do you know what is the proper way to read this annotation?
Fill example: https://pastebin.com/KbBAZVfB
Upvotes: 2
Views: 1265
Reputation: 16559
First of all, I don't think com.validation.ValidateCharacteristicsProcessor
exist in your project. Still if you are trying to load that class (if present), then check whether this class is annotated with @Fix
or not.
I'm showing with TestClass that you have provided.
I tried a simple approach.
First, I created a simple maven project to demonstrate two approaches.
Using Java Reflections.
Using Spring Core as you are using it in the Test method.
Project Structure :
Fix.java
package com.example;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(TYPE)
public @interface Fix {
public String[] author() default "";
}
TestClass.java
package com.example;
@Fix(author = "John Doe")
public class TestClass {
public void test() {
}
}
Main.java
package com.example;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
// create an instance of TestClass
TestClass t = new TestClass();
// use reflection to extract annotation from TestClass.class
Fix fix = t.getClass().getAnnotation(Fix.class); // or TestClass.class.getAnnotation(Fix.class);
// print the value
System.out.println(fix.author()[0]);
}
}
Output :
If you want to carry on with the code that you have provided, then I have a fix given below.
I have researched about ResourcePatternResolver
and I think you are using spring-core
to read classes.
So, I have updated your code.
package com.example;
import java.io.IOException;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
ResourcePatternResolver resolversec = new PathMatchingResourcePatternResolver();
Class<?> cl = resolversec.getClassLoader().loadClass("com.example.TestClass");
if (cl != null) {
System.out.println("Class is not null " + cl.getSimpleName());
}
Fix fix = cl.getAnnotation(Fix.class);
if (fix != null) {
System.out.println("!!!! " + fix.author()[0]);
}
}
}
Output :
pom.xml
:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>read-annotations</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Upvotes: 5
Reputation: 142
You are loading in-correct class in your code. You should load TestClass as the Fix annotation is on TestClass, not on ValidateCharacteristicsProcessor class
Upvotes: 1
Reputation: 1116
Iterate class with native java or with library in package look this link: Can you find all classes in a package using reflection?
After it iterate and show with this code:
Arrays.stream(getClasses("package.name.asdf")).forEach(aClass -> {
Fix annotation = (Fix) aClass.getAnnotation(Fix.class);
if (annotation != null) System.out.println(Arrays.asList(annotation.author()));
});
Upvotes: 1
Reputation: 48874
You are calling getAnnotation(Fix.class)
on com.validation.ValidateCharacteristicsProcessor
, not on TestClass
. The annotation is present as expected on TestClass
:
jshell> TestClass.class.getAnnotations()
$4 ==> Annotation[1] { @Fix(author={"John Doe"}) }
jshell> TestClass.class.getAnnotation(Fix.class)
$5 ==> @Fix(author={"John Doe"})
jshell> TestClass.class.getAnnotation(Fix.class).author()[0]
$6 ==> "John Doe"
Looking at your full example, I would guess that either predictedName
is not the right string, or that the class you're inspecting is actually not annotated properly.
It would likely help to create a small MCVE of the desired behavior and then reincorporate that back into your larger project once you have a basic approach working.
Upvotes: 5