[jboss-user] [JBoss AOP] - Field interception doesn't work........

robotics80 do-not-reply at jboss.com
Thu Dec 21 17:49:18 EST 2006


I have three classes like these:

public class SqtpSkeleton{
  |    protected Log objLog=null;
  |    // and so on...
  | }
  | 
  | public class SqtpService extends SqtpSkeleton{
  |    //other fields and methods.....
  | }
  | 
  | public class MyService extends SqtpService{
  |    public void init(){
  |       objLog = new Log("c:/logFile.log",255);
  |    }
  |    public void execute(){
  |       objLog.write("START");
  |       //do something
  |    }
  | }

Now I want to intercept the logObject of MyService class, because I want to use the same log object declared in MyService class, in a LogInterceptor. I want this behaviour because the LogInterceptor have to log operations in the same file that the class use for its own logging.
Initially I have created an aspect with two advices where the first advice intercept the FieldWriteInvocation to the object Log objLog in MyService class, and the second advice to intercept any other invocation such as MethodInvocation or ConstructorInvocation that uses the intercepted log object by the first advice.
Here is the example of the code for my Aspect:

public class LogAspect {
  | 	private static final String className = "LogAspect";
  | 	private static final String DBG_ERROR = "ERROR";
  | 	private static final String DBG_WARNING = "WARNING";
  | 	private static final String DBG_INFO = "INFO";
  | 	private static final String DBG_TRACE = "TRACE";
  | 	private String propertyFile;
  | 	private Log log;
  |         
  |     	
  |     public void setPropertyFile(String propertyFile) {
  | 		this.propertyFile = propertyFile;
  | 	}
  | 	
  | 	public void setLog(Log log) {
  | 		this.log = log;
  | 	}
  | 	
  | 	public String getName() {
  | 		return "LogAspect";
  | 	}
  | 	
  | 	public Object getLogger(Invocation invocation) throws Throwable{
  | 		try{
  | 			System.out.println("INGRESSO nel getLogger() for " + Thread.currentThread().getName());
  | 			if (invocation instanceof FieldWriteInvocation) {
  | 				FieldWriteInvocation fieldInvocation = (FieldWriteInvocation)invocation;
  | 				setLog((Log)fieldInvocation.getValue());
  | 			} else 
  | 				System.out.println("Unknown Invocation!!");
  | 			return invocation.invokeNext();
  | 		} finally {
  | 			System.out.println("USCITA dal getLogger() for " + Thread.currentThread().getName());
  | 		}
  | 	}
  | 	
  | 	public Object trace(Invocation invocation) throws Throwable{
  | 		String proc = className + ".trace()";
  | 		long startTime = System.currentTimeMillis();
  | 		logInfo(proc, "START");
  | 		logTrace(proc, invocationTypeValue(invocation));
  | 		Object response = null;
  | 		try {
  | 			response = invocation.invokeNext();
  | 			return response;	
  | 		}catch(Throwable t) {
  | 			long endTime = System.currentTimeMillis();
  | 	        long elapsedTime = endTime - startTime;
  | 			logErr(proc, t.getMessage() + " - Tempo di esecuzione (ms): " + elapsedTime);
  | 	        throw t;
  | 		}
  | 		finally {
  | 	        long endTime = System.currentTimeMillis();
  | 	        long elapsedTime = endTime - startTime;
  | 	        logTrace(proc,dumpInvocationResponse(invocation, response) + " - Tempo di esecuzione (ms): " + elapsedTime);
  | 	        logInfo(proc, "END");
  | 		}
  | 	}
  | 	 
  | 	
  | 	/**
  | 	 * visualizza informazioni utili circa la risposta della chiamata
  | 	 * @param l'oggetto invocation, contenente il tipo di chiamata intercettatta dall'interceptor
  | 	 * @return la stringa indicante il valore di ritorno del metodo intercettato (se presente)
  | 	 */
  | 	public String dumpInvocationResponse(Invocation invocation, Object response) {
  | 		
  | 		StringBuffer buffer = new StringBuffer();
  | 		String genericName;
  | 		String returnType;
  | 		String modifier;
  | 		if (invocation instanceof MethodInvocation) {
  | 			MethodInvocation methodInvocation = (MethodInvocation)invocation;
  | 			genericName = methodInvocation.getMethod().getName();
  | 			returnType = methodInvocation.getMethod().getReturnType().getName();
  | 			modifier = Modifier.toString(methodInvocation.getMethod().getModifiers());
  | 			buffer.append(modifier + " ").append(returnType + " ").append(genericName).append("()");
  | 			buffer.append(" ( return ");
  | 			if (response == null)
  | 				buffer.append("NULL");
  | 			else 
  | 				buffer.append(response.getClass().getSimpleName()).append(":").append(response.toString());	
  | 			buffer.append(" )");
  | 		}else if(invocation instanceof ConstructorInvocation) {
  | 			ConstructorInvocation cInvocation = (ConstructorInvocation)invocation;
  | 			genericName = cInvocation.getConstructor().getDeclaringClass().getSimpleName();
  | 			modifier = Modifier.toString(cInvocation.getConstructor().getModifiers());
  | 			buffer.append(modifier + " ").append(genericName).append("()");
  | 		}
  | 		return buffer.toString();
  | 	}
  | 	
  | 	/**
  | 	 * Metodo che ritorna la stringa rappresentante la 'Signature' del metodo o del costruttore 
  | 	 * wrappato dalla MethodInvocation o ConstructorInvocation.
  | 	 * La 'Signature' è composta dal nome del metodo / costruttore, preceduto da eventuali modificatori, e dalla lista di parametri
  | 	 * che lo compongono organizzata per 'tipo;valore', in cui il valore è l'informazione a runtime del suddetto parametro
  | 	 * @param Invocation l'oggetto per il tipo di invocazione 
  | 	 * @return la stringa contenente la signature del metodo / costruttore invocato
  | 	 */
  | 	private String invocationTypeValue (Invocation invocation) {
  | 		
  | 		String genericName;
  | 		String returnType;
  | 		String modifier;
  | 		Object[] argumentsValue; 
  | 		Class[] argumentsType; 
  | 		//Class[] exception;  
  | 		StringBuffer buffer = new StringBuffer();
  | 		
  | 		if (invocation instanceof MethodInvocation) {
  | 			MethodInvocation mi = (MethodInvocation)invocation;
  | 			genericName = mi.getMethod().getName();
  | 			returnType = mi.getMethod().getReturnType().getName();
  | 			modifier = Modifier.toString(mi.getMethod().getModifiers());
  | 			argumentsValue = mi.getArguments();
  | 			argumentsType = mi.getMethod().getParameterTypes();
  | 			//exception = mi.getMethod().getExceptionTypes();
  | 			buffer.append(modifier + " ").append(returnType + " ").append(genericName);
  | 			if (argumentsType == null || argumentsType.length == 0) {
  | 				buffer.append("()");
  | 				return buffer.toString();
  | 			}
  | 		} else if (invocation instanceof ConstructorInvocation) {
  | 				ConstructorInvocation ci = (ConstructorInvocation)invocation;
  | 				genericName = ci.getConstructor().getDeclaringClass().getSimpleName();
  | 				modifier = Modifier.toString(ci.getConstructor().getModifiers());
  | 		    	argumentsValue = ci.getArguments();
  | 		    	argumentsType = ci.getConstructor().getParameterTypes();
  | 		    	//exception = ci.getConstructor().getExceptionTypes();
  | 		    	buffer.append(modifier + " ").append(genericName);
  | 		    	if (argumentsType == null || argumentsType.length == 0) {
  | 		    		buffer.append("()");
  | 					return buffer.toString();
  | 				}
  | 		} else {
  | 	         	return "Unknown " + invocation;
  | 	    }
  | 		
  | 		//buffer.append(genericName.substring(0, genericName.indexOf('(')));
  | 		if (argumentsValue.length != argumentsType.length) 
  | 			System.out.println("Type");//throw new RuntimeException(" Type and Value mismatch");
  | 		for (int i = 0; i < argumentsValue.length; i++) {
  | 			if(i == 0)
  | 				buffer.append(" (");
  | 			if(argumentsType.isArray()){
  | 				Object[] arrayArgument = (Object[])argumentsValue;
  | 				buffer.append(argumentsType.getSimpleName()).append(":");
  | 				if(arrayArgument.length > 20)
  | 					buffer.append("Lenght = " + arrayArgument.length);
  | 				else
  | 					buffer.append(Arrays.toString(arrayArgument));
  | 			}else
  | 				buffer.append(argumentsType.getSimpleName()).append(":").append(argumentsValue.toString());
  | 			if( i == argumentsValue.length - 1){
  | 				buffer.append(")");
  | 				break;
  | 			}
  | 			buffer.append(", ");
  | 		}
  | 		/*
  | 		if(exception != null && exception.length > 0){
  | 			buffer.append(" throws ");
  | 			for (int i = 0; i < exception.length; i++) {
  | 				buffer.append(exception.getName());
  | 				if (i == exception.length-1)
  | 					break;
  | 				buffer.append(", ");
  | 			}
  | 		}*/
  | 		return buffer.toString();
  | 	}
  | 	
  |     private void logErr(String proc, String message) {
  |     	System.out.println(DBG_ERROR + ": " + message);
  |     	if (log != null) {
  |             log.logWrite(log.DBG_ERROR, proc, message);
  |         }
  |     }
  |    
  |     private void logWarning(String proc, String message) {
  |     	System.out.println(DBG_WARNING + ": " + message);
  |     	if (log != null) {
  |             log.logWrite(log.DBG_WARNING, proc, message);
  |         }
  |     }
  |     
  |     private void logInfo(String proc, String message) {
  |     	System.out.println(DBG_INFO + ": " + message);
  |     	if (log != null) {
  |             log.logWrite(log.DBG_INFO, proc, message);
  |         }
  |     }
  |     
  |     private void logTrace(String proc, String message) {
  |     	System.out.println(DBG_TRACE + ": " + message);
  |     	if (log != null) {
  |             log.logWrite(log.DBG_TRACE, proc, message);
  |         }
  |     }
  | 
  | }

Here is my jboss-aop.xml for binding aspect to pointucts:
<aop>
  |     <!-- Declarigng pointucs -->
  |     <pointcut name="logObject" expr="set(util.log.Log test.aop.MyService->objLog)"/>
  |     <pointcut name="logMethod" expr="execution(public * test.aop.MyService->*(..))"/>
  |     
  |     <pointcut name="logObject_2" expr="set(util.log.Log $instanceof{test.aop.SqtpSkeleton}->*)"/>
  |     
  |     <!-- Declaring Aspect -->
  |     <aspect name="LogAspect" class="test.aop.LogAspect" scope="PER_INSTANCE"/>
  |     
  |     <!-- Bind pountcuts to aspects --> 
  |     <bind pointcut="logObject">
  |         <advice name="getLogger" aspect="LogAspect"/>
  |     </bind>
  |     
  |     <bind pointcut="logMethod">
  |         <advice name="trace" aspect="LogAspect"/>
  |     </bind>
  |     
  | </aop>

The main problem is that the LogAspect doesn't intercept the FieldWriteInvocation on object objLog in MyService class, so I can't use this for logging operation in the trace() advice. If I use the second pointcut expression :

<pointcut name="logObject_2" expr="set(util.log.Log $instanceof{test.aop.SqtpSkeleton}->*)"/>

the Aspect intercept the invocation but, it only see the FieldWrite (objLog = null) in the SqtpSkeleton class, and not in its inherited classes so If call FieldWriteInvocation.getValue(), it returns null.
How can I solve this problem?
Do you have any suggestions or alternative strategy to avoid this problem?
Please help me!!!

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3995729#3995729

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3995729




More information about the jboss-user mailing list