Get Java EE 6 interceptors working (Weld on GlassFish 3.1)
I'm working on a project where I want to use Interceptors to log usage of a ManagedBean. As I read in the specs and in many examples it should be possible with the current CDI implementations. The code is mainly copied from examples like the Glassfish JavaEE Tutorial or other sources I found on the web. There is no special implementation in it. It should only log.
What I try was the following:
LoggedInterceptor.java
package test.interceptors;
import java.io.Serializable;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {
private static final long serialVersionUID = 1L;
public LoggedInterceptor() {
}
@AroundInvoke
public Object logMethodEntry(InvocationContext invocationContext)
throws Exception {
System.out.println(
"Entering method: " + invocationContext.getMethod().getName()
+ " in class "
+ invocationContext.getMethod().getDeclaringClass().getName());
return invocationContext.proceed();
}
}
Logged.java
package test.interceptors;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;
@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({
METHOD,
TYPE
})
public @interface Logged {
}
WEB-INF/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>test.interceptors.LoggedInterceptor</class>
</interceptors>
</beans>
MainController.class
// ... All imports
@Named
@SessionScoped
@Logged
public class MainController implements Serializable {
// Code goes here
}
What I get is a class not found Exception from the WELD Resource Loader.
[#|2011-04-04T14:03:37.394+0200|SEVERE|glassfish3.1|javax.enterprise.system.tools.admin.org.glassfish.deployment.admin|_ThreadID=31;_ThreadName=Thread-1;|Exception while loading the app : Error loading class test.interceptors.LoggedInterceptor
org.jboss.weld.resources.spi.ResourceLoadingException: Error loading class test.interceptors.LoggedInterceptor
at org.jboss.weld.resources.DefaultResourceLoader.classForName(DefaultResourceLoader.java:61)
at org.jboss.weld.manager.Enabled$ClassLoader.apply(Enabled.java:67)
at org.jboss.weld.manager.Enabled$ClassLoader.apply(Enabled.java:55)
at com.google.common.collect.Lists$TransformingRandomAccessList.get(Lists.java:435)
at java.util.AbstractList$Itr.next(AbstractList.java:345)
at org.jboss.weld.manager.Enabled.createMetadataMap(Enabled.java:130)
at org.jboss.weld.manager.Enabled.<init>(Enabled.java:100)
at org.jboss.weld.manager.Enabled.of(Enabled.java:82)
at org.jboss.weld.bootstrap.BeanDeployment.<init>(BeanDeployment.java:104)
at org.jboss.weld.bootstrap.WeldBootstrap$DeploymentVisitor.visit(WeldBootstrap.java:185)
at org.jboss.weld.bootstrap.WeldBootstrap$DeploymentVisitor.visit(WeldBootstrap.java:156)
at org.jboss.weld.bootstrap.WeldBootstrap.startContainer(WeldBootstrap.java:287)
at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:167)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:128) 开发者_运维知识库
at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:262)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:460)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:370)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1067)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1247)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1235)
at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:465)
at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:222)
at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:168)
at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:234)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.ClassNotFoundException: test.interceptors.LoggedInterceptor
at com.sun.enterprise.loader.ASURLClassLoader.findClassData(ASURLClassLoader.java:808)
at com.sun.enterprise.loader.ASURLClassLoader.findClass(ASURLClassLoader.java:696)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at org.jboss.weld.resources.DefaultResourceLoader.classForName(DefaultResourceLoader.java:52)
... 42 more
Good news (well, kind of) - your code works like a charm on my machine (GlassFish 3.1, with Netbeans 7.0 RC1).
Here's what I did:
- Created a new Java EE project in Netbeans (with war module)
- Added support for CDI / JSF 2
- Used your classes (all in the war)
- Filled MainController with something loggable
package test.web;
import java.io.Serializable; import java.util.Date; import javax.enterprise.context.SessionScoped; import javax.inject.Named; import test.interceptors.Logged;
@Named @Logged @SessionScoped public class MainController implements Serializable { public void callMe() { System.out.println("called at " + new Date()); } }
Added trivial JSF page
<h:form> <h:outputText value="hallo" /> <h:commandButton action="#{mainController.callMe}" label="jo" /> </h:form>
Clicked button and checked output ;-)
INFO: Entering method: callMe in class test.web.MainController INFO: called at Tue Apr 05 13:41:41 CEST 2011
That's pretty much it. Seems like your project setup is the problem - you might want to start again with a fresh project...?
精彩评论