Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions impl/src/main/java/org/jboss/weld/bootstrap/Validator.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.enterprise.context.Dependent;
import jakarta.enterprise.context.NormalScope;
import jakarta.enterprise.event.Event;
Expand All @@ -62,8 +65,12 @@
import jakarta.inject.Named;
import jakarta.inject.Provider;
import jakarta.inject.Scope;
import jakarta.interceptor.AroundConstruct;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.AroundTimeout;

import org.jboss.weld.annotated.enhanced.EnhancedAnnotated;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedMethod;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType;
import org.jboss.weld.bean.AbstractBean;
import org.jboss.weld.bean.AbstractClassBean;
Expand Down Expand Up @@ -127,6 +134,17 @@
*/
public class Validator implements Service {

private static final Collection<Class<? extends Annotation>> interceptionTypes;

static {
interceptionTypes = new HashSet<>();
interceptionTypes.add(AroundInvoke.class);
interceptionTypes.add(AroundConstruct.class);
interceptionTypes.add(AroundTimeout.class);
interceptionTypes.add(PostConstruct.class);
interceptionTypes.add(PreDestroy.class);
}

private final Set<PlugableValidator> plugableValidators;

private final Map<Bean<?>, Boolean> resolvedInjectionPoints;
Expand Down Expand Up @@ -566,6 +584,17 @@ protected void validateInterceptor(Interceptor<?> interceptor, BeanManagerImpl m
if (!annotated.getDeclaredEnhancedMethodsWithAnnotatedParameters(Disposes.class).isEmpty()) {
throw ValidatorLogger.LOG.interceptorsCannotHaveDisposerMethods(interceptor);
}
for (Class<? extends Annotation> type : interceptionTypes) {
Collection<EnhancedAnnotatedMethod<?, ?>> declaredEnhancedMethods = (Collection<EnhancedAnnotatedMethod<?, ?>>) annotated
.getDeclaredEnhancedMethods(type);
if (declaredEnhancedMethods.size() > 1) {
throw ValidatorLogger.LOG.interceptorsCannotHaveMoreThanOneMethodPerType(annotated.getJavaClass(),
type.getName(),
declaredEnhancedMethods.stream()
.map(enhancedAnnotatedMethod -> enhancedAnnotatedMethod.getJavaMember().toString())
.collect(Collectors.toList()));
}
}
annotated = annotated.getEnhancedSuperclass();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.jboss.weld.logging.WeldLogger.WELD_PROJECT_CODE;

import java.lang.reflect.Method;
import java.util.Collection;

import org.jboss.logging.Logger;
import org.jboss.logging.Logger.Level;
Expand Down Expand Up @@ -319,4 +320,8 @@ DefinitionException interceptorMethodDeclaresMultipleParameters(Object param1, O

@Message(id = 1490, value = "Bean type {0} is not proxyable because it is sealed - {1}.", format = Format.MESSAGE_FORMAT)
UnproxyableResolutionException notProxyableSealedType(Object param1, Object param2);

@Message(id = 1491, value = "An interceptor {0} cannot have more than one method per interception type. Following methods were found for interception type {1}: {2}.", format = Format.MESSAGE_FORMAT)
DefinitionException interceptorsCannotHaveMoreThanOneMethodPerType(Class<?> interceptorClass, String interceptionType,
Collection<String> interceptionMethods);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.jboss.weld.tests.interceptors.multipleMethods;

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
@MyBinding
public class FooBean {

public String ping() {
return "Foo";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.jboss.weld.tests.interceptors.multipleMethods;

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

@Interceptor
@Priority(1)
@MyBinding
public class InvalidFooInterceptor {

// Note that WFLY does similar detection for around invoke already
// https://github.com/wildfly/wildfly/blob/36.0.0.Beta1/ee/src/main/java/org/jboss/as/ee/logging/EeLogger.java#L1061-L1070

@PostConstruct
public Object method1(InvocationContext ctx) throws Exception {
return ctx.proceed() + "intercept2";
}

@PostConstruct
public Object method2(InvocationContext ctx) throws Exception {
return ctx.proceed() + "intercept";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.jboss.weld.tests.interceptors.multipleMethods;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import jakarta.interceptor.InterceptorBinding;

@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface MyBinding {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.jboss.weld.tests.interceptors.multipleMethods;

import jakarta.enterprise.inject.spi.DefinitionException;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.BeanArchive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.weld.test.util.Utils;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(Arquillian.class)
public class SeveralMethodsForSameInterceptionTypeTest {

@Deployment
@ShouldThrowException(DefinitionException.class)
public static JavaArchive getDeployment() {
return ShrinkWrap
.create(BeanArchive.class, Utils.getDeploymentNameAsHash(SeveralMethodsForSameInterceptionTypeTest.class))
.addPackage(SeveralMethodsForSameInterceptionTypeTest.class.getPackage());
}

@Test
public void testMultipleMethodsAreDetected() {
// no-op, test should throw exception
}
}
Loading