Skip to content

Commit 2244f53

Browse files
committed
APT ignores @Inject fields in superclass when generating Mvc route constructors
- fix #3804
1 parent f20b251 commit 2244f53

File tree

7 files changed

+142
-3
lines changed

7 files changed

+142
-3
lines changed

modules/jooby-apt/src/main/java/io/jooby/internal/apt/MvcRouter.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,7 @@ private StringBuilder constructors(String generatedName, boolean kt) {
196196
// Inject could be at constructor or field level.
197197
var injectConstructor =
198198
constructors.stream().filter(hasInjectAnnotation()).findFirst().orElse(null);
199-
var inject =
200-
injectConstructor != null
201-
|| getTargetType().getEnclosedElements().stream().anyMatch(hasInjectAnnotation());
199+
var inject = injectConstructor != null || hasInjectAnnotation(getTargetType());
202200
final var defaultConstructor =
203201
constructors.stream().filter(it -> it.getParameters().isEmpty()).findFirst().orElse(null);
204202
if (inject) {
@@ -306,6 +304,21 @@ private StringBuilder constructors(String generatedName, boolean kt) {
306304
return trimr(buffer).append(System.lineSeparator());
307305
}
308306

307+
private boolean hasInjectAnnotation(TypeElement targetClass) {
308+
var inject = false;
309+
while (!inject && !targetClass.toString().equals("java.lang.Object")) {
310+
// Look up at field/setter injection
311+
inject = targetClass.getEnclosedElements().stream().anyMatch(hasInjectAnnotation());
312+
targetClass =
313+
(TypeElement)
314+
context
315+
.getProcessingEnvironment()
316+
.getTypeUtils()
317+
.asElement(getTargetType().getSuperclass());
318+
}
319+
return inject;
320+
}
321+
309322
private static Predicate<Element> hasInjectAnnotation() {
310323
var injectAnnotations =
311324
Set.of("javax.inject.Inject", "jakarta.inject.Inject", "com.google.inject.Inject");
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package tests.i3804;
7+
8+
import jakarta.inject.Inject;
9+
10+
public class Base3804 {
11+
@Inject protected Service3804 paramDecoder;
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package tests.i3804;
7+
8+
import io.jooby.Context;
9+
import io.jooby.annotation.GET;
10+
import io.jooby.annotation.Path;
11+
12+
@Path("/3804")
13+
public class C3804 extends Base3804 {
14+
@GET
15+
public Object list(Context ctx) {
16+
return paramDecoder; // paramDecoder is null
17+
}
18+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package tests.i3804;
7+
8+
import io.jooby.Context;
9+
import io.jooby.annotation.GET;
10+
import io.jooby.annotation.Path;
11+
import jakarta.inject.Inject;
12+
13+
@Path("/3804")
14+
public class C3804b {
15+
@Inject protected Service3804 paramDecoder;
16+
17+
@GET
18+
public Object list(Context ctx) {
19+
return paramDecoder; // paramDecoder is null
20+
}
21+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package tests.i3804;
7+
8+
import io.jooby.Context;
9+
import io.jooby.annotation.GET;
10+
import io.jooby.annotation.Path;
11+
import jakarta.inject.Inject;
12+
13+
@Path("/3804")
14+
public class C3804c {
15+
private Service3804 paramDecoder;
16+
17+
@GET
18+
public Object list(Context ctx) {
19+
return paramDecoder; // paramDecoder is null
20+
}
21+
22+
@Inject
23+
public void setParamDecoder(Service3804 paramDecoder) {
24+
this.paramDecoder = paramDecoder;
25+
}
26+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package tests.i3804;
7+
8+
import static org.junit.jupiter.api.Assertions.assertTrue;
9+
10+
import org.junit.jupiter.api.Test;
11+
12+
import io.jooby.apt.ProcessorRunner;
13+
14+
public class Issue3804 {
15+
@Test
16+
public void shouldDetectDIOnFieldsOfBaseClass() throws Exception {
17+
new ProcessorRunner(new C3804())
18+
.withSourceCode(
19+
source -> {
20+
assertTrue(source.contains("setup(ctx -> ctx.require(type));"));
21+
});
22+
}
23+
24+
@Test
25+
public void shouldDetectDIOnFields() throws Exception {
26+
new ProcessorRunner(new C3804b())
27+
.withSourceCode(
28+
source -> {
29+
assertTrue(source.contains("setup(ctx -> ctx.require(type));"));
30+
});
31+
}
32+
33+
@Test
34+
public void shouldDetectDIOnSetter() throws Exception {
35+
new ProcessorRunner(new C3804c())
36+
.withSourceCode(
37+
source -> {
38+
assertTrue(source.contains("setup(ctx -> ctx.require(type));"));
39+
});
40+
}
41+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package tests.i3804;
7+
8+
public class Service3804 {}

0 commit comments

Comments
 (0)