我有两个不同的项目: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)。
有没有人知道可能出现什么问题?
答案 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)并测试拦截器。