diff --git a/libraries/pom.xml b/libraries/pom.xml
index 7823732224..a6179a843d 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -699,6 +699,12 @@
${reflections.version}
+
+ io.github.classgraph
+ classgraph
+ ${classgraph.version}
+
+
@@ -916,6 +922,7 @@
2.7.1
3.6
0.9.11
+ 4.8.22
diff --git a/libraries/src/test/java/com/baeldung/classgraph/ClassGraphUnitTest.java b/libraries/src/test/java/com/baeldung/classgraph/ClassGraphUnitTest.java
new file mode 100644
index 0000000000..5767396948
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/classgraph/ClassGraphUnitTest.java
@@ -0,0 +1,78 @@
+package com.baeldung.classgraph;
+
+import io.github.classgraph.*;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ClassGraphUnitTest {
+
+ @Test
+ public void whenClassAnnotationFilterIsDefined_thenTargetClassesCanBeFound() {
+ doTest(result -> {
+ ClassInfoList classInfos = result.getClassesWithAnnotation(TestAnnotation.class.getName());
+ assertThat(classInfos).extracting(ClassInfo::getName).contains(ClassWithAnnotation.class.getName());
+ });
+ }
+
+ @Test
+ public void whenMethodAnnotationFilterIsDefined_thenTargetClassesCanBeFound() {
+ doTest(result -> {
+ ClassInfoList classInfos = result.getClassesWithMethodAnnotation(TestAnnotation.class.getName());
+ assertThat(classInfos).extracting(ClassInfo::getName).contains(MethodWithAnnotation.class.getName());
+ });
+ }
+
+ @Test
+ public void whenMethodAnnotationValueFilterIsDefined_thenTargetClassesCanBeFound() {
+ doTest(result -> {
+ ClassInfoList classInfos = result.getClassesWithMethodAnnotation(TestAnnotation.class.getName());
+ ClassInfoList filteredClassInfos = classInfos.filter(classInfo -> {
+ return classInfo.getMethodInfo().stream().anyMatch(methodInfo -> {
+ AnnotationInfo annotationInfo = methodInfo.getAnnotationInfo(TestAnnotation.class.getName());
+ if (annotationInfo == null) {
+ return false;
+ }
+
+ return "web".equals(annotationInfo.getParameterValues().getValue("value"));
+ });
+ });
+ assertThat(filteredClassInfos)
+ .extracting(ClassInfo::getName)
+ .contains(MethodWithAnnotationParameterWeb.class.getName());
+ });
+ }
+
+ @Test
+ public void whenFieldAnnotationFilterIsDefined_thenTargetClassesCanBeFound() {
+ doTest(result -> {
+ ClassInfoList classInfos = result.getClassesWithFieldAnnotation(TestAnnotation.class.getName());
+ assertThat(classInfos).extracting(ClassInfo::getName).contains(FieldWithAnnotation.class.getName());
+ });
+ }
+
+ @Test
+ public void whenResourceIsUsed_thenItCanBeFoundAndLoaded() throws IOException {
+ try (ScanResult result = new ClassGraph().whitelistPaths("classgraph").scan()) {
+ ResourceList resources = result.getResourcesWithExtension("config");
+ assertThat(resources).extracting(Resource::getPath).containsOnly("classgraph/my.config");
+ assertThat(resources.get(0).getContentAsString()).isEqualTo("my data");
+ }
+ }
+
+ private void doTest(Consumer checker) {
+ try (ScanResult result = new ClassGraph().enableAllInfo()
+ .whitelistPackages(getClass().getPackage().getName())
+ .scan())
+ {
+ checker.accept(result);
+ }
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/classgraph/ClassWithAnnotation.java b/libraries/src/test/java/com/baeldung/classgraph/ClassWithAnnotation.java
new file mode 100644
index 0000000000..0f3eeef293
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/classgraph/ClassWithAnnotation.java
@@ -0,0 +1,5 @@
+package com.baeldung.classgraph;
+
+@TestAnnotation
+public class ClassWithAnnotation {
+}
diff --git a/libraries/src/test/java/com/baeldung/classgraph/FieldWithAnnotation.java b/libraries/src/test/java/com/baeldung/classgraph/FieldWithAnnotation.java
new file mode 100644
index 0000000000..c5d1cc6062
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/classgraph/FieldWithAnnotation.java
@@ -0,0 +1,7 @@
+package com.baeldung.classgraph;
+
+public class FieldWithAnnotation {
+
+ @TestAnnotation
+ private String s;
+}
diff --git a/libraries/src/test/java/com/baeldung/classgraph/MethodWithAnnotation.java b/libraries/src/test/java/com/baeldung/classgraph/MethodWithAnnotation.java
new file mode 100644
index 0000000000..12d0c9927c
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/classgraph/MethodWithAnnotation.java
@@ -0,0 +1,8 @@
+package com.baeldung.classgraph;
+
+public class MethodWithAnnotation {
+
+ @TestAnnotation
+ public void service() {
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/classgraph/MethodWithAnnotationParameterDao.java b/libraries/src/test/java/com/baeldung/classgraph/MethodWithAnnotationParameterDao.java
new file mode 100644
index 0000000000..9e38f42013
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/classgraph/MethodWithAnnotationParameterDao.java
@@ -0,0 +1,8 @@
+package com.baeldung.classgraph;
+
+public class MethodWithAnnotationParameterDao {
+
+ @TestAnnotation("dao")
+ public void service() {
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/classgraph/MethodWithAnnotationParameterWeb.java b/libraries/src/test/java/com/baeldung/classgraph/MethodWithAnnotationParameterWeb.java
new file mode 100644
index 0000000000..1ef3d46b6f
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/classgraph/MethodWithAnnotationParameterWeb.java
@@ -0,0 +1,8 @@
+package com.baeldung.classgraph;
+
+public class MethodWithAnnotationParameterWeb {
+
+ @TestAnnotation("web")
+ public void service() {
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/classgraph/TestAnnotation.java b/libraries/src/test/java/com/baeldung/classgraph/TestAnnotation.java
new file mode 100644
index 0000000000..f47ec180a9
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/classgraph/TestAnnotation.java
@@ -0,0 +1,14 @@
+package com.baeldung.classgraph;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+
+@Target({TYPE, METHOD, FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TestAnnotation {
+
+ String value() default "";
+}
diff --git a/libraries/src/test/resources/classgraph/my.config b/libraries/src/test/resources/classgraph/my.config
new file mode 100644
index 0000000000..b99df573f6
--- /dev/null
+++ b/libraries/src/test/resources/classgraph/my.config
@@ -0,0 +1 @@
+my data
\ No newline at end of file