Bytecode Instrumentation is done using Instrumentors. Jour configuration files defines which Instrumentor should be called for class and its methods.
instrumentor.instrumentClass would be called.
instrumentor.instrumentMethod or instrumentor.instrumentConstructor would be called.
To create your own instrumentor you should know Javassist. And follow provided examples:
If instrumentClass
This file is used to define what kind of instrumentation would be applied and to which classes and methods.
<jour> <aspect type="net.sf.jour.instrumentor.MakeEmptyMethodInstrumentor"> <typedef>com.solect.*</typedef> <pointcut expr="* debug*(..)"/> </aspect> </jour>
This will instrument all classes that have functions like debug.
Consider original code.
public class ClassWithDebug { public ClassWithDebug(String param) { debug("ClassWithDebug created", param); } public void debug(String message, String v) { System.out.println(message + " " + v); } }
This is how the code will look after instrumentation and decompilation
public class ClassWithDebug { public ClassWithDebug(String param) { debug("ClassWithDebug created", param); } public void debug(String message, String v) { } }
This is how the code will look after instrumentation processing by ProGuard and decompilation
public class ClassWithDebug { public ClassWithDebug(String param) { } }
Predevined values are
Custom instrumentor should implement net.sf.jour.instrumentor.Instrumentor
Examples:
<typedef>*.*Test</typedef>
<typedef>net.sf.jour.examples.*</typedef>
Examples:
<pointcut expr="junit.framework.Test suite()">
<pointcut expr="* get*()">
<pointcut expr="!final * get*()">
public private synchronized static modifiers can be used
<pointcut expr="* *(..)|!* set*(..)">
<pointcut expr="java.lang.String *(..)">
<pointcut expr="java.lang.String;int *(..)">
<pointcut expr="* *(java.lang.String,int)">
<pointcut expr="* *(java.lang.String|int)">
<pointcut expr="* com.exmple.MyInterface->*(..)">
This translates to method call "propertyName(String);
Example:
<jour> <aspect type="net.sf.jour.instrumentor.ExceptionCatcherInstrumentor" enabled="true"> <typedef>uut.exceptionCatcher.*Case</typedef> <pointcut expr="* throwMethod*()"/> <property name="exceptionType" value="java.lang.Error"/> <property name="code"> <value><![CDATA[ { caught = $e; return; } ]]></value> </property> </aspect> </jour>