Skip to content

Commit cb03c1f

Browse files
authored
Merge pull request #358 from netgrif/NAE-2204
[NAE-2204] Plugin EntryPoint class cannot resolve annotation when proxyed by Spring
2 parents 0bc8695 + d541edd commit cb03c1f

5 files changed

Lines changed: 70 additions & 32 deletions

File tree

application-engine/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@
135135
<artifactId>nae-user-ce</artifactId>
136136
<version>${project.version}</version>
137137
</dependency>
138+
<dependency>
139+
<groupId>com.netgrif</groupId>
140+
<artifactId>nae-spring-core-adapter</artifactId>
141+
<version>${project.version}</version>
142+
</dependency>
138143

139144
<!-- Loader -->
140145
<dependency>

application-engine/src/main/groovy/com/netgrif/application/engine/integration/modules/ModuleServiceInjector.groovy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ package com.netgrif.application.engine.integration.modules
33
import com.netgrif.application.engine.configuration.ApplicationContextProvider
44
import com.netgrif.application.engine.startup.ApplicationEngineFinishRunner
55
import com.netgrif.application.engine.startup.annotation.RunnerOrder
6+
import com.netgrif.application.engine.adapter.spring.utils.NaeReflectionUtils
67
import org.slf4j.Logger
78
import org.slf4j.LoggerFactory
89
import org.springframework.boot.ApplicationArguments
910
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
11+
import org.springframework.core.annotation.AnnotatedElementUtils
1012
import org.springframework.stereotype.Component
1113

1214
/**
@@ -75,7 +77,8 @@ class ModuleServiceInjector implements ApplicationEngineFinishRunner {
7577
private Map<String, Map<String, Object>> groupServicesByModule(Map<String, Object> services) {
7678
Map<String, Map<String, Object>> grouped = [(DEFAULT_KEY): [:]]
7779
services.each { entry ->
78-
ModuleService[] annotations = entry.value.getClass().getAnnotationsByType(ModuleService.class)
80+
Class serviceClass = NaeReflectionUtils.resolveClass(entry.value)
81+
ModuleService[] annotations = serviceClass.getAnnotationsByType(ModuleService.class)
7982
if (annotations.length == 0) throw new IllegalStateException("Module Service bean must have @ModuleService annotations")
8083
ModuleService annotation = annotations[0]
8184
if (annotation.value().isBlank()) {

application-engine/src/main/java/com/netgrif/application/engine/startup/ApplicationRunnerExecutor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import java.util.Map;
1414

15-
import static com.netgrif.application.engine.startup.ApplicationRunnerOrderResolver.resolveClass;
15+
import static com.netgrif.application.engine.adapter.spring.utils.NaeReflectionUtils.resolveClass;
1616

1717
@Slf4j
1818
@Component

application-engine/src/main/java/com/netgrif/application/engine/startup/ApplicationRunnerOrderResolver.java

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
import lombok.Getter;
99
import lombok.RequiredArgsConstructor;
1010
import lombok.extern.slf4j.Slf4j;
11-
import org.springframework.aop.support.AopUtils;
1211
import org.springframework.stereotype.Component;
1312

1413
import java.lang.annotation.Annotation;
1514
import java.util.*;
1615
import java.util.function.Function;
1716

17+
import static com.netgrif.application.engine.adapter.spring.utils.NaeReflectionUtils.indexOfClass;
18+
import static com.netgrif.application.engine.adapter.spring.utils.NaeReflectionUtils.resolveClass;
19+
1820
@Slf4j
1921
@Component
2022
@RequiredArgsConstructor
@@ -54,11 +56,6 @@ public <T> SortedRunners<T> sortByRunnerOrderAnnotation(Collection<T> runners) {
5456
return new SortedRunners<>(ordered.values().stream().flatMap(List::stream).toList(), unresolved);
5557
}
5658

57-
public static <T> Class<?> resolveClass(T object) {
58-
if (object instanceof Class) return (Class<?>) object;
59-
else return AopUtils.isAopProxy(object) ? AopUtils.getTargetClass(object) : object.getClass();
60-
}
61-
6259
@Getter
6360
public static class SortedRunners<T> {
6461
private final List<T> sorted;
@@ -91,7 +88,6 @@ public SortedRunners(List<T> sorted, List<T> unresolved) {
9188
* @return {@code true} if all unresolved runners have been successfully sorted and the unresolved list is empty;
9289
* {@code false} otherwise.
9390
*/
94-
9591
public boolean resolveAllRunners() {
9692
sortUnresolvedRunners();
9793
replaced.values().forEach(this::removeRunner);
@@ -171,29 +167,6 @@ protected boolean replaceRunner(T item) {
171167
return changed;
172168
}
173169

174-
/**
175-
* Returns the index of the first occurrence of the specified class in the given list.
176-
* If the list contains an element whose class matches the specified class, the index of that element is returned.
177-
* If the specified class is {@code null}, the method returns the index of the first {@code null} element in the list.
178-
* If the list is {@code null} or empty, or if the class is not found, the method returns {@code -1}.
179-
*
180-
* @param <I> the type of elements in the list
181-
* @param list the list to search for the specified class
182-
* @param clazz the class to search for in the list
183-
* @return the index of the first occurrence of the specified class in the list, or {@code -1} if the class is not found
184-
*/
185-
public static <I> int indexOfClass(List<I> list, Class<?> clazz) {
186-
if (list == null) return -1;
187-
if (list.isEmpty()) return -1;
188-
if (clazz == null) return list.indexOf(null);
189-
for (int i = 0; i < list.size(); i++) {
190-
if (resolveClass(list.get(i)).equals(clazz)) {
191-
return i;
192-
}
193-
}
194-
return -1;
195-
}
196-
197170
}
198171

199172
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.netgrif.application.engine.adapter.spring.utils;
2+
3+
import org.springframework.aop.framework.AopProxyUtils;
4+
5+
import java.util.List;
6+
import java.util.Objects;
7+
8+
public final class NaeReflectionUtils {
9+
10+
private NaeReflectionUtils() {
11+
throw new IllegalStateException("No instances. Utility class");
12+
}
13+
14+
/**
15+
* Resolves and returns the {@code Class} object for the given input object.
16+
* If the input object is a {@code Class}, it is returned directly.
17+
* If the input object is an AOP proxy, the target class of the proxy is returned.
18+
* Otherwise, the class of the object is returned.
19+
*
20+
* @param <T> the type of the input object
21+
* @param object the object for which the {@code Class} needs to be resolved
22+
* @return the {@code Class} object corresponding to the input object or null if null value provided
23+
*/
24+
public static <T> Class<?> resolveClass(T object) {
25+
if (object == null) return null;
26+
if (object instanceof Class) return (Class<?>) object;
27+
return AopProxyUtils.ultimateTargetClass(object);
28+
}
29+
30+
/**
31+
* Returns the index of the first occurrence of the specified class in the given list.
32+
* If the list contains an element whose class matches the specified class, the index of that element is returned.
33+
* If the specified class is {@code null}, the method returns the index of the first {@code null} element in the list.
34+
* If the list is {@code null} or empty, or if the class is not found, the method returns {@code -1}.
35+
*
36+
* @param <I> the type of elements in the list
37+
* @param list the list to search for the specified class
38+
* @param clazz the class to search for in the list
39+
* @return the index of the first occurrence of the specified class in the list, or {@code -1} if the class is not found
40+
*/
41+
public static <I> int indexOfClass(List<I> list, Class<?> clazz) {
42+
if (list == null) return -1;
43+
if (list.isEmpty()) return -1;
44+
if (clazz == null) return list.indexOf(null);
45+
for (int i = 0; i < list.size(); i++) {
46+
I item = list.get(i);
47+
if (item == null) continue;
48+
Class<?> itemClass = resolveClass(item);
49+
if (Objects.equals(itemClass, clazz)) {
50+
return i;
51+
}
52+
}
53+
return -1;
54+
}
55+
56+
57+
}

0 commit comments

Comments
 (0)