为什么我的拦截器无法正常工作?

时间:2015-11-11 15:12:57

标签: java-ee cdi interceptor

我有两个不同的项目:A和B.

B包含一个我希望在项目A中使用的拦截器,以及将来的项目C和D.

我在两个项目中使用jboss-javaee-6.0版本3.0.3.Final(这意味着,CDI版本1.0)。

项目B(不包含beans.xml):

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

@Interceptor
@PerformanceLog
public class LoggingInterceptor {
    private static final Logger LOG = LoggerFactory.getLogger(LoggingInterceptor.class);

    @AroundInvoke
    public Object logMethodEntry(InvocationContext ctx) throws Exception {
        LOG.debug("Entered method (" + ctx.getMethod().getName() + ") of class (" + ctx.getMethod().getClass() + ").");
    }
}

项目A(包含beans.xml):

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>commons.utils.logging.performanceInterceptor.LoggingInterceptor</class>
</interceptors>
</beans>

MyControllerC:

@Named
@RequestScoped
public class MyControllerC implements Serializable {
     ... 

    @PerformanceLog
    public void init() {
       //do some BD access here
    }
}

当我部署应用程序时,我收到错误

weblogic.management.DeploymentException: org.jboss.weld.exceptions.DeploymentException: WELD-001417 Enabled interceptor class <class>commons.utils.logging.performanceInterceptor.LoggingInterceptor    </class> in file:/D:/projectos/myProject/target/myProject/WEB-INF/beans.xml@7 is neither annotated @Interceptor nor registered through a portable extension:org.jboss.weld.exceptions.DeploymentException:WELD-001417 Enabled interceptor class <class>commons.utils.logging.performanceInterceptor.LoggingInterceptor</class> in file:/D:/projectos/myProject/target/myProject/WEB-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 com.oracle.injection.provider.weld.WeldInjectionContainer.start(WeldInjectionContainer.java:110)
at com.oracle.injection.integration.CDIAppDeploymentExtension.initCdi(CDIAppDeploymentExtension.java:76)

我的第一次尝试是因为Interceptor位于项目A lib中的jar中,所以它是不可见的。我升级到java-ee 7版本1.0.3.Final和CDI 1.1,以便我可以在LoggingInterceptor中使用标记@Priority。错误消失了,但它没有工作(没有写入日志)。所以我回到了java-ee 6版本3.0.3.Final和CDI 1.0。

我猜测也许我找不到拦截器,因为beans.xml中的路径不是jar中的正确路径(它位于\ WEB-INF \ lib \ loggings-1.2.jar \ commons \中utils的\记录\ performanceInterceptor)。

有没有人知道可能出现什么问题?

3 个答案:

答案 0 :(得分:1)

您问题下面的评论指出了一个很好的方向。

项目B应该是所谓的bean archive - 在Java EE 6中,通过在这样的档案中包含beans.xml来实现(即使是完全空的内容也足够了)。

你说:

  

项目B不是一个Web应用程序,这就是为什么它没有beans.xml。这是一个横向项目,为众多项目提供了共同的功能

你有点不对 - beans.xml在你的情况下仍然必须存在。在JAR存档中,它应放在src/main/resources/META-INF/文件夹中(如果您使用的是maven)。

对于WAR包装,它应放在src/main/webapp/WEB-INF/

还有一件事:你在评论中说了两个相反的陈述:

  

项目B不是网络应用

还有:

  

如果我将一个beans.xml添加到Project B(...)(/ webapp/WEB-INF/beans.xml,因为它是一场战争

那么真相是什么?

答案 1 :(得分:1)

我有一个类似的问题,我的Interceptor没有被要求使用某些注释方法,而在其他方法上却起作用。 问题在于,没有插入使用Interceptor批注的类(RESTClient.java),而是通过构造函数对其进行了初始化。 为了解决这个问题,我做了这样的事情:

@Inject
private Provider<RESTClient> restClientProvider;
//..
RESTClient restClient = restClientProvider.get();
restClient.init(
//do whatever the constructor was doing here.
);

答案 2 :(得分:0)

1)在您的beans.xml中添加标签bean-discovery-mode,如上例所示:

<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="all">
    <interceptors>
        <class>YOUR_CLASS__FROM_THE_JAR</class>
    </interceptors>
</beans>

2)在包含拦截器的jar中,在src/main/resources内添加一个名为META-INF的文件夹,并在beans.xml文件中添加<interceptors>标记。

这对我有用。

另外,尝试使用方法main在类中创建独立容器(我推荐WELD)并测试拦截器。