Skip to content

Commit d18f6d2

Browse files
authored
Merge pull request quarkusio#49853 from jonasrutishauser/arc-fix-proxy-of-abstract-class-with-interface
ArC: fix interception proxy of abstract classes with interfaces
2 parents 6fe68be + 26d6f17 commit d18f6d2

File tree

3 files changed

+242
-1
lines changed

3 files changed

+242
-1
lines changed

independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/InterceptionProxyGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ private void createInterceptionSubclass(ClassOutput classOutput, InterceptionPro
325325
}
326326
}
327327

328-
ResultHandle superResult = isInterface
328+
ResultHandle superResult = method.declaringClass().isInterface()
329329
? funcBytecode.invokeInterfaceMethod(methodDescriptor, targetHandle, superParamHandles)
330330
: funcBytecode.invokeVirtualMethod(methodDescriptor, targetHandle, superParamHandles);
331331
funcBytecode.returnValue(superResult != null ? superResult : funcBytecode.loadNull());
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package io.quarkus.arc.test.interceptors.producer;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import java.lang.annotation.ElementType;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.RetentionPolicy;
8+
import java.lang.annotation.Target;
9+
10+
import jakarta.annotation.Priority;
11+
import jakarta.enterprise.context.Dependent;
12+
import jakarta.enterprise.inject.Produces;
13+
import jakarta.interceptor.AroundInvoke;
14+
import jakarta.interceptor.Interceptor;
15+
import jakarta.interceptor.InterceptorBinding;
16+
import jakarta.interceptor.InvocationContext;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.api.extension.RegisterExtension;
20+
21+
import io.quarkus.arc.Arc;
22+
import io.quarkus.arc.InterceptionProxy;
23+
import io.quarkus.arc.NoClassInterceptors;
24+
import io.quarkus.arc.test.ArcTestContainer;
25+
26+
public class ProducerWithAbstractClassAndInterfaceInterceptionTest {
27+
@RegisterExtension
28+
public ArcTestContainer container = new ArcTestContainer(MyBinding1.class, MyInterceptor1.class,
29+
MyBinding2.class, MyInterceptor2.class, MyProducer.class);
30+
31+
@Test
32+
public void test() {
33+
MyNonbeanBase nonbean = Arc.container().instance(MyNonbeanBase.class).get();
34+
assertEquals("intercepted1: hello1_foobar", nonbean.hello1());
35+
assertEquals("intercepted1: hello2_foobar", nonbean.hello2());
36+
assertEquals("hello3", nonbean.hello3());
37+
assertEquals("hello4_foobar", nonbean.hello4());
38+
assertEquals("hello5", nonbean.hello5());
39+
}
40+
41+
@Retention(RetentionPolicy.RUNTIME)
42+
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR })
43+
@InterceptorBinding
44+
@interface MyBinding1 {
45+
}
46+
47+
@MyBinding1
48+
@Priority(1)
49+
@Interceptor
50+
static class MyInterceptor1 {
51+
@AroundInvoke
52+
Object intercept(InvocationContext ctx) throws Exception {
53+
return "intercepted1: " + ctx.proceed();
54+
}
55+
}
56+
57+
@Retention(RetentionPolicy.RUNTIME)
58+
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR })
59+
@InterceptorBinding
60+
@interface MyBinding2 {
61+
}
62+
63+
@MyBinding2
64+
@Priority(2)
65+
@Interceptor
66+
static class MyInterceptor2 {
67+
@AroundInvoke
68+
Object intercept(InvocationContext ctx) throws Exception {
69+
return "intercepted2: " + ctx.proceed();
70+
}
71+
}
72+
73+
interface MyNonbean {
74+
String hello1();
75+
76+
@MyBinding2 // this should be ignored, because interceptor bindings are ignored on interfaces
77+
String hello2();
78+
79+
@MyBinding2 // this should be ignored, because interceptor bindings are ignored on interfaces
80+
@NoClassInterceptors
81+
default String hello3() {
82+
return "hello3";
83+
}
84+
85+
@NoClassInterceptors
86+
String hello4();
87+
88+
@NoClassInterceptors
89+
default String hello5() {
90+
return "hello5";
91+
};
92+
}
93+
94+
@MyBinding1
95+
abstract static class MyNonbeanBase implements MyNonbean {
96+
}
97+
98+
static class MyNonbeanImpl extends MyNonbeanBase {
99+
private final String value;
100+
101+
MyNonbeanImpl(String value) {
102+
this.value = value;
103+
}
104+
105+
@Override
106+
public String hello1() {
107+
return "hello1_" + value;
108+
}
109+
110+
@Override
111+
public String hello2() {
112+
return "hello2_" + value;
113+
}
114+
115+
@Override
116+
public String hello4() {
117+
return "hello4_" + value;
118+
}
119+
}
120+
121+
@Dependent
122+
static class MyProducer {
123+
@Produces
124+
MyNonbeanBase produce(InterceptionProxy<MyNonbeanBase> proxy) {
125+
return proxy.create(new MyNonbeanImpl("foobar"));
126+
}
127+
}
128+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package io.quarkus.arc.test.interceptors.producer;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import java.lang.annotation.ElementType;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.RetentionPolicy;
8+
import java.lang.annotation.Target;
9+
10+
import jakarta.annotation.Priority;
11+
import jakarta.enterprise.context.Dependent;
12+
import jakarta.enterprise.inject.Produces;
13+
import jakarta.interceptor.AroundInvoke;
14+
import jakarta.interceptor.Interceptor;
15+
import jakarta.interceptor.InterceptorBinding;
16+
import jakarta.interceptor.InvocationContext;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.junit.jupiter.api.extension.RegisterExtension;
20+
21+
import io.quarkus.arc.Arc;
22+
import io.quarkus.arc.BindingsSource;
23+
import io.quarkus.arc.InterceptionProxy;
24+
import io.quarkus.arc.NoClassInterceptors;
25+
import io.quarkus.arc.test.ArcTestContainer;
26+
27+
public class ProducerWithAbstractClassWithInterfaceInterceptionAndBindingsSourceTest {
28+
@RegisterExtension
29+
public ArcTestContainer container = new ArcTestContainer(MyBinding1.class, MyInterceptor1.class,
30+
MyBinding2.class, MyInterceptor2.class, MyProducer.class);
31+
32+
@Test
33+
public void test() {
34+
MyNonbeanBase nonbean = Arc.container().instance(MyNonbeanBase.class).get();
35+
assertEquals("intercepted1: hello1", nonbean.hello1());
36+
assertEquals("intercepted1: intercepted2: hello2", nonbean.hello2());
37+
assertEquals("intercepted2: hello3", nonbean.hello3());
38+
}
39+
40+
@Retention(RetentionPolicy.RUNTIME)
41+
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR })
42+
@InterceptorBinding
43+
@interface MyBinding1 {
44+
}
45+
46+
@MyBinding1
47+
@Priority(1)
48+
@Interceptor
49+
static class MyInterceptor1 {
50+
@AroundInvoke
51+
Object intercept(InvocationContext ctx) throws Exception {
52+
return "intercepted1: " + ctx.proceed();
53+
}
54+
}
55+
56+
@Retention(RetentionPolicy.RUNTIME)
57+
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR })
58+
@InterceptorBinding
59+
@interface MyBinding2 {
60+
}
61+
62+
@MyBinding2
63+
@Priority(2)
64+
@Interceptor
65+
static class MyInterceptor2 {
66+
@AroundInvoke
67+
Object intercept(InvocationContext ctx) throws Exception {
68+
return "intercepted2: " + ctx.proceed();
69+
}
70+
}
71+
72+
interface MyNonbean {
73+
String hello1();
74+
}
75+
76+
abstract static class MyNonbeanBase implements MyNonbean {
77+
public abstract String hello2();
78+
79+
public String hello3() {
80+
return "hello3";
81+
}
82+
}
83+
84+
static class MyNonbeanImpl extends MyNonbeanBase {
85+
@Override
86+
public String hello1() {
87+
return "hello1";
88+
}
89+
90+
@Override
91+
public String hello2() {
92+
return "hello2";
93+
}
94+
}
95+
96+
@MyBinding1
97+
static abstract class MyNonbeanBindings {
98+
@MyBinding2
99+
abstract String hello2();
100+
101+
@MyBinding2
102+
@NoClassInterceptors
103+
abstract String hello3();
104+
}
105+
106+
@Dependent
107+
static class MyProducer {
108+
@Produces
109+
MyNonbeanBase produce(@BindingsSource(MyNonbeanBindings.class) InterceptionProxy<MyNonbeanBase> proxy) {
110+
return proxy.create(new MyNonbeanImpl());
111+
}
112+
}
113+
}

0 commit comments

Comments
 (0)