I have a method that throws IOException which is called from a java timer run().Since the run() doesn't return any checked exceptions and I am using AspectJ for logging, how do I log the exception in aspectj?
This is my code:
timer = new Timer();
`
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
for (OidTypes oidType : typesList) {
try {
valueIncrementOperation(oidType);//------this method throws exception
} catch (IOException e) {
System.out.println("Error occured inside Timer : "
+ e.getMessage());
timer.cancel();
timer = null;
}
}
` I am forced to use try/catch for now. What are my options?
First you need to pack the IOException into an unchecked exception, the real exception will be the cause of the exception you catch in the advice.
The simplest is to take RuntimeException.
public void doTimerJob() {
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
throw new IOException("file not found");
} catch (IOException e) {
timer.cancel();
throw new RuntimeException(e);
}
}
}, new Date(), 2000);
}
Then you could try the following:
Create a point cut for TimerTask#run
pointcut timerTaskRun() : execution(public * java.util.TimerTask.run(..) );
and an advice for after throwing a RuntimeException
after() throwing(RuntimeExceptione) : timerTaskRun() {
System.out.println("log and rethrow " + e.getCause().getMessage());
}
This will re-throw the exception after logging it.
If you want to log and swallow the exception you could write an around advice
Object around() : timerTaskRun() {
Object o;
try {
o = proceed();
} catch(RuntimeException e) {
System.out.println("log and swallow " + e.getCause().getMessage());
o = null;
}
return o;
}
Note that you should only have only one of the advices, either after throwing
or around
not both.
But you may not want to advice all TimerTask#run
calls along with all RuntimeException
s. In this case you should create own types which you should use in the point cut and the advices.
"Unchecked" IOException
public class IOExceptionUnchecked extends RuntimeException {
private static final long serialVersionUID = 1L;
public IOExceptionUnchecked(IOException e) {
super(e);
}
}
Custom TimerTask
public class MyTimerTask extends TimerTask {
Timer owner = null;
public MyTimerTask(Timer timer) {this.owner = timer;}
@Override
public void run() {
try {
throw new IOException("file not found");
} catch (IOException e) {
owner.cancel();
throw new IOExceptionUnchecked(e);
}
}
}
Point cut
pointcut timerTaskRun() : execution(public * com.example.MyTimerTask.run(..) );
after throwing advice:
after() throwing(IOExceptionUnchecked e) : timerTaskRun() {
System.out.println("log and rethrow " + e.getCause().getMessage());
}
Or around advice
Object around() : timerTaskRun() {
Object o;
try {
o = proceed();
} catch(IOExceptionUnchecked e) {
System.out.println("log and swallow " + e.getCause().getMessage());
o = null;
}
return o;
}