My dev environment is: WildFly 8.1, CDI, EJB 3.2, JDK 1.7. App is packed as an ear archive (one ejb + one war) because probably it gonna have other web modules in the future.
I'm struggling with a custom @InterceptorBinding
type used inside my EJB stateless bean.
@Inherited
@InterceptorBinding
@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@Documented
public @interface DetectIntegrityConstraintsViolation {
}
@javax.annotation.ManagedBean // make it a CDI bean. @Interceptor itself should be enough, but WildFly 8.1 seems to have a bug, since it doesn't work without this line.
@Interceptor
@DetectIntegrityConstraintsViolation
public class ReferentialIntegrityConstraintViolationInterceptor {
@PersistenceContext
private EntityManager em;
@Resource
private SessionContext sessionContext;
// ....
}
beans.xml:
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="annotated">
<interceptors>
<class>com.xxx.ejb.ReferentialIntegrityConstraintViolationInterceptor</class>
</interceptors>
</beans>
When I'm calling my EJB method through REST service I'm getting Error injecting resource into CDI managed bean
:
javax.naming.NameNotFoundException: Caused by java.lang.IllegalStateException: JBAS011048: Failed to construct component instance Caused by: java.lang.IllegalArgumentException: JBAS016081: Error injecting resource into CDI managed bean.
Can't find a resource named java:comp/env/com.xxx.ejb.ReferentialIntegrityConstraintViolationInterceptor/sessionContext defined on private javax.ejb.SessionContext com.xxx.ejb.ReferentialIntegrityConstraintViolationInterceptor.sessionContext at org.jboss.as.weld.services.bootstrap.WeldResourceInjectionServices.resolveResource(WeldResourceInjectionServices.java:188) [wildfly-weld-8.1.0.Final.jar:8.1.0.Final]
So walking in the dark, I've moved to the ResourceLookup approach:
@ManagedBean
@Interceptor
@DetectIntegrityConstraintsViolation
public class ReferentialIntegrityConstraintViolationInterceptor {
@PersistenceContext
private EntityManager em;
private SessionContext sessionContext;
@PostConstruct
public void init(InvocationContext ctx) {
try {
InitialContext ic = new InitialContext();
this.sessionContext = (SessionContext)ic.lookup("java:comp/EJBContext");
} catch (NamingException ex) {
throw new RuntimeException(ex.getMessage());
}
}
// .....
}
Then Injection started to work, but I got a new error:
Caused by: org.jboss.weld.exceptions.DefinitionException: WELD-000619: An interceptor for lifecycle callbacks Interceptor [class com.xxx.ejb.ReferentialIntegrityConstraintViolationInterceptor intercepts @DetectIntegrityConstraintsViolation] declares and interceptor binding interface com.xxx.ejb.DetectIntegrityConstraintsViolation with METHOD as its @Target.
So when removed from the DetectIntegrityConstraintsViolation
a METHOD
target:
@Inherited
@InterceptorBinding
@Target({ TYPE /*, METHOD*/ }) // CRUCIAL
@Retention(RUNTIME)
@Documented
public @interface DetectIntegrityConstraintsViolation {
}
Then it started to work. But why??
And why I cannot have my annotation placed on the method? Do somebody know?
BTW: what is even more strange, when i'm not using @InterceptorBinding
, but plain old:
@Override
// @DetectIntegrityConstraintsViolation
@Interceptors(ReferentialIntegrityConstraintViolationInterceptor.class)
public User updateUser(final User user) {
// ...
}
Interceptor works flawlessly even on a method level.
I find EJB and Weld so awkward to use...