0

The CDI interceptor that records the method entry and exit in the log file is not being called for the singleton class by the container?

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface Logit {
}

Here is the interceptor:

@Interceptor
@Logit
public class RecordIntereceptor implements Serializable {
    private static final long serialVersionUID = -2230122751970857900L;
    public RecordIntereceptor() {
    }
    @AroundInvoke
    public Object logEntryExit(InvocationContext ctx)throws Exception{
        String methodName = ctx.getMethod().getName();
        String declaringClass= ctx.getMethod().getDeclaringClass().getCanonicalName();
        Logger logger = Logger.getLogger(declaringClass);
        logger.entering("List Service Intereceptor "+declaringClass, methodName);
        Object result = ctx.proceed();
        logger.exiting("List Service Intereceptor "+declaringClass, methodName);
        return result;
    }
}

Here is a singleton class using the interceptor:

@Logit
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class DataLoaderSessionBean {
 @PostConstruct
    public void createData() {
        removeStartupData();
        loadUsers();
        loadParts();
    }
...........
...........
}

Finally the beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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"
       bean-discovery-mode="annotated">
    <interceptors>
        <class>org.me.jsfproject.intereceptor.RecordIntereceptor</class>
    </interceptors>
</beans>

There is no method entry or exit logs for the method DataLoaderSessionBean.createData() in the log file. Using the debugger, I step through the code and the interceptor is not being called by the container. Although the interceptor works fine for non-singleton classes? Any idea why this is happening?


There seem to be restrictions with Interceptors that have life cycle methods (i.e. @postConstruct) they must be of @Target({TYPE}) so I created an additional new Interceptor interface and a new Interceptor merely for the Singleton class as follow:

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({TYPE})
public @interface LifeCycleLogger {
}

@Interceptor
@LifeCycleLogger

public class LifeCycleIntereceptor implements Serializable {
    private static final long serialVersionUID = -2230122753370857601L;
    public LifeCycleIntereceptor() {
    }
   
    @PostConstruct
    public void logPostConstruct(InvocationContext ctx){
        String methodName = ctx.getMethod().getName();
        String declaringClass= ctx.getMethod().getDeclaringClass().getCanonicalName();
        Logger logger = Logger.getLogger(declaringClass);
        logger.entering("Life Cycle Intereceptor "+declaringClass, methodName);
        try {
            ctx.proceed();
        } catch (Exception e) {
            logger.log(Level.SEVERE, "LifeCycle Interceptor Post Construct caught an exception: {0}", e.getMessage());
        }
        
        logger.exiting("Life Cycle Intereceptor "+declaringClass, methodName);
    }
}

I changed the Singleton as follow:

@LifeCycleLogger
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class DataLoaderSessionBean{

................
    public DataLoaderSessionBean(){
        
    }

    @PostConstruct
    public void createData() {
        ........
        
    }
............
}

However, there are no entry or exit logs for the createData() method?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Darvin
  • 148
  • 8

1 Answers1

0

As createData() is a lifecycle method of DataLoaderSessionBean it doesn't get captured by the @AroundInvoke annotation.

To declare a method in the interceptor that captures the @PostConstruct lifecycle call, you have to annotate it with this same annotation:

@PostConstruct
public void logPostConstruct(InvocationContext ctx) throws Exception{
    String methodName = ctx.getMethod().getName();
    String declaringClass= ctx.getMethod().getDeclaringClass().getCanonicalName();
    Logger logger = Logger.getLogger(declaringClass);
    logger.entering("List Service Intereceptor "+declaringClass, methodName);
    ctx.proceed();
    logger.exiting("List Service Intereceptor "+declaringClass, methodName);
}
areus
  • 2,880
  • 2
  • 7
  • 17
  • Areus, thanks for the comment. I have updated my original post to reflect your proposed comments, however, the lifecycle method for the singleton is not being intercepted. Any idea? – Darvin Jan 27 '21 at 06:22
  • did you add the new `LifeCycleIntereceptor` to the `beans.xml` file? – areus Jan 27 '21 at 08:20
  • Oops! Thanks, I mark your response to this post. I have also had a pending question on your other post. – Darvin Jan 27 '21 at 09:02