开发者

@AroundInvoke in a CDI project

开发者 https://www.devze.com 2023-03-20 00:02 出处:网络
There are 3 projects that use CDI. Project A has an Interceptor for transaction control. Project B uses Project A to save data in a database. When I run these unit tests, everything passes.

There are 3 projects that use CDI. Project A has an Interceptor for transaction control.

Project B uses Project A to save data in a database. When I run these unit tests, everything passes.

Project C uses Project B for integration tests. These tests fails when it finds the @AroundInvoke annotation from Interceptor.

What is going wrong? The interceptor is only in Project B beans.xml.

The exception stacktrace doesn't clear up my mind. It only show a jassist error. Deb开发者_如何学Cugging, I found that the problem comes from boostrap.deploybeans() inside Weld. So, I commented the @AroundInvoke in the interceptor class and everything goes fine with tests, but the insert on database. I think that happens because I removed the interceptor that creates transaction for inserts.

The code:

1) There is a project A which defines an annotation and an interceptor for this annotation. Example:

/Annotation/

@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Transactional {
}

/Interceptor/

@Interceptor
@Transactional
public class TransactionalInterceptor implements Serializable {
    …
    @AroundInvoke
    public Object intercept(InvocationContext context) throws Exception {
        …
    }
    …
}

I think this project must have an empty /META-INF/beans.xml.

2) There is another project B that uses the interceptor from project A. Example:

public class ProjectBClass {
    …
    @Transactional
    public void interceptorMethod() {
        …
    }
    …
}

So I think this project must have a /META-INF/beans.xml that enables the interceptor. Example:

<beans>
<interceptors>
<class>br.com.company.projecta.TransactionalInterceptor</class>
</interceptors>
</beans>

3) Finally, there's a project C that uses the method from project B. Example:

public class ProjectCClass {
    …
    private ProjectBClass projectBClass;
    …
    public void testerMethod() {
        …
        this.projectBClass.interceptorMethod();
        …
    }
    …
}

I am not sure if it must have a /META-INF/beans.xml.

4) In this same project, there is an integration test which tests the method. Example:

public class ProjectCClassTest {
   …
   @Test
   public void test() {
      ProjectCClass projectCClass = new ProjectCClass();
      projectCClass.testerMethod();
      …
      Assert.assertEquals(…);
   }
   …
}    


You need META-INF/beans.xml in all projects (packaged as .jar)

You should not instantiate the classes yourself. If you do, they are not CDI managed. Let CDI instantiated them. For example look here.

0

精彩评论

暂无评论...
验证码 换一张
取 消