I have an interceptor that appears to be loaded correctly by JBoss (EAP 6.4) when I use it in a web app, but is rejected when I use the same beans.xml in a weld-se context.
package com.stackoverflow;
import javax.enterprise.context.Dependent;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Interceptor
@BindingAnnotation
@Dependent
public class InterceptorTest {
@AroundInvoke
public Object crypto(InvocationContext invocationContext) throws Exception {
return null;
}
}
And a Test:
package com.stackoverflow;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import org.junit.Before;
import org.junit.Test;
public class InterceptorTestTest {
WeldContainer container;
@Before
public void setup(){
Weld weld = new Weld();
container = weld.initialize();
}
@Test
public void crypto() throws Exception {
}
}
When I run the test:
[main] INFO org.jboss.weld.Version - WELD-000900 1.1.28 (Final)
[main] INFO org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
org.jboss.weld.exceptions.DeploymentException: WELD-001417 Enabled interceptor class <class>com.stackoverflow.InterceptorTest</class> in file:/Users/pstanden/IdeaProjects/crypto/test/target/test-classes/META-INF/beans.xml@7 is neither annotated @Interceptor nor registered through a portable extension
at org.jboss.weld.bootstrap.Validator.validateEnabledInterceptorClasses(Validator.java:503)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:373)
at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:379)
at org.jboss.weld.bootstrap.api.helpers.ForwardingBootstrap.validateBeans(ForwardingBootstrap.java:85)
I can't really work out what I should be adding or removing, and why Weld org.jboss.weld.se:weld-se:1.1.28.Final seems to do different things to the same version of weld in JBoss?
EDIT: My beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>com.stackoverflow.InterceptorTest</class>
</interceptors>
</beans>
Edit again my pom:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>com.stackoverflow</groupId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<modelVersion>4.0.0</modelVersion>
<artifactId>test</artifactId>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>1.1.28.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.javaee</groupId>
<artifactId>javaee</artifactId>
<version>6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
Alright, managed to reproduce your problem and understood what you were doing. For the record it worked for me because I run it as a main method, not as a test.
The problem here is that you are using plain JUnit and your classes are in src/test
- Weld won't pick them up, or rather, won't scan them and identify them as beans/interceptors etc. Therefore, your interceptor won't be found and the definition in beans.xml
will be invalid leading to the exception you see.This is a known problem with JUnit as it is not sufficient to test CDI.
To workaround this, you can place these classes into src/main
and they should be picked up correctly. But chances are, sooner or later you will bump into similar problems.
To truly resolve this, I suggest you twrite tests using Arquillian
as a framework and Arquillian-container-Weld
as a container in which it runs. Note that this is still SE (although Arquillian is used for EE testing too). It allows you to create a test archive and put inside whatever you deem worthy and Weld will pick it up all.
To inspire yourself, you can take a look at Weld testsuite, where the same thing is used in SE testing. Here is a link to one such test.