Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ArC: fix InvocationContext#setParameters() #34003

Merged
merged 1 commit into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@
* <p>
* Note that context data and method parameters are mutable and are not guarded/synchronized. We expect them to be modified
* before or after dispatch. If modified before and after dispatch an unpredictable behavior may occur.
* <p>
* Note that {@link #getParameters()} only reflects modifications of the current interceptor. If an interceptor with higher
* priority in the same chain calls {@link #setParameters(Object[])} then the changes are not reflected.
*
*/
class AroundInvokeInvocationContext extends AbstractInvocationContext {

Expand Down Expand Up @@ -71,7 +67,7 @@ private Object proceed(int currentPosition) throws Exception {
if (currentPosition < metadata.chain.size()) {
// Invoke the next interceptor in the chain
return metadata.chain.get(currentPosition)
.invoke(new NextAroundInvokeInvocationContext(currentPosition + 1, parameters));
.invoke(new NextAroundInvokeInvocationContext(currentPosition + 1));
} else {
// Invoke the target method
return metadata.aroundInvokeForward.apply(target, this);
Expand All @@ -91,11 +87,9 @@ private Object proceed(int currentPosition) throws Exception {
class NextAroundInvokeInvocationContext implements ArcInvocationContext {

private final int position;
protected Object[] parameters;

public NextAroundInvokeInvocationContext(int position, Object[] parameters) {
public NextAroundInvokeInvocationContext(int position) {
this.position = position;
this.parameters = parameters;
}

@Override
Expand Down Expand Up @@ -125,13 +119,12 @@ public Constructor<?> getConstructor() {

@Override
public Object[] getParameters() {
return parameters;
return AroundInvokeInvocationContext.this.getParameters();
}

@Override
public void setParameters(Object[] params) {
validateParameters(metadata.method, params);
this.parameters = params;
AroundInvokeInvocationContext.this.setParameters(params);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.arc.test.interceptors.parameters.setter;

import static org.junit.jupiter.api.Assertions.assertEquals;

import jakarta.annotation.Priority;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InvocationContext;

@Setter
@Priority(1)
@Interceptor
public class FirstSetterInterceptor {

@AroundInvoke
Object fooAroundInvoke(InvocationContext ctx) throws Exception {
assertEquals("bar", ctx.getParameters()[0]);
ctx.setParameters(new String[] { "first" });
Object ret = ctx.proceed();
// getParameters() should return the value set by the interceptor with higher priority
assertEquals("second", ctx.getParameters()[0]);
return ret;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.arc.test.interceptors.parameters.setter;

import static org.junit.jupiter.api.Assertions.assertEquals;

import jakarta.annotation.Priority;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InvocationContext;

@Setter
@Priority(2)
@Interceptor
public class SecondSetterInterceptor {

@AroundInvoke
Object fooAroundInvoke(InvocationContext ctx) throws Exception {
assertEquals("first", ctx.getParameters()[0]);
ctx.setParameters(new String[] { "second" });
assertEquals("second", ctx.getParameters()[0]);
return ctx.proceed();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.quarkus.arc.test.interceptors.parameters.setter;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.arc.Arc;
import io.quarkus.arc.test.ArcTestContainer;

public class SetParamsTest {

@RegisterExtension
public ArcTestContainer container = new ArcTestContainer(TheBean.class, Setter.class, FirstSetterInterceptor.class,
SecondSetterInterceptor.class);

@Test
public void testSetParameters() {
assertEquals("second", Arc.container().instance(TheBean.class).get().foo("bar"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.quarkus.arc.test.interceptors.parameters.setter;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import jakarta.interceptor.InterceptorBinding;

@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@Documented
@InterceptorBinding
public @interface Setter {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.quarkus.arc.test.interceptors.parameters.setter;

import jakarta.enterprise.context.Dependent;

@Dependent
public class TheBean {

@Setter
String foo(String val) {
return val;
}

}