Search code examples
glassfishjava-ee-6introspectionperformancecounter

Glassfish - JEE6 - Use of Interceptor to measure performance


For measuring execution time of methods, I've seen suggestions to use

public class PerformanceInterceptor {
   @AroundInvoke
   Object measureTime(InvocationContext ctx) throws Exception {
   long beforeTime = System.currentTimeMillis();
   Object obj = null;
   try {
      obj = ctx.proceed();
      return obj;
   }
   finally {
      time = System.currentTimeMillis() - beforeTime;
      // Log time
   }
}

Then put

@Interceptors(PerformanceInterceptor.class) 

before whatever method you want measured.

Anyway I tried this and it seems to work fine.

I also added a

public static long countCalls = 0;

to the PerformanceInterceptor class and a

countCalls++; 

to the measureTime() which also seems to work o.k.

With my newby hat on, I will ask if my use of the countCalls is o.k. i.e that Glassfish/JEE6 is o.k. with me using static variables in a Java class that is used as an Interceptor.... in particular with regard to thread safety. I know that normally you are supposed to synchronize setting of class variables in Java, but I don't know what the case is with JEE6/Glassfish. Any thoughts ?


Solution

  • There is not any additional thread safety provided by container in this case. Each bean instance does have its own instance of interceptor. As a consequence multiple thread can access static countCalls same time.

    That's why you have to guard both reads and writes to it as usual. Other possibility is to use AtomicLong:

    private static final AtomicLong callCount = new AtomicLong();
    
    private long getCallCount() {
       return callCount.get();
    }
    
    private void increaseCountCall() {
       callCount.getAndIncrement();
    }
    

    As expected, these solutions will work only as long as all of the instances are in same JVM, for cluster shared storage is needed.