The Problem
I'm running multiple invocations of some external method via an ExecutorService. I would like to be able to interrupt these methods, but unfortunately they do not check the interrupt flag by themselves. Is there any way I can force an exception to be raised from these methods?
I am aware that throwing an exception from an arbitrary location is potentially dangerous, in my specific case I am willing to take this chance and prepared to deal with the consequences.
Details
By "external method" I mean some method(s) that come from an external library, and I cannot modify its code (well I can, but that will make it a maintenance nightmare whenever a new version is released).
The external methods are computationally expensive, not IO-bound, so they don't respond to regular interrupts and I can't forcefully close a channel or a socket or something. As I've mentioned before, they also do not check the interrupt flag.
The code is conceptually something like:
// my code
public void myMethod() {
Object o = externalMethod(x);
}
// External code
public class ExternalLibrary {
public Object externalMethod(Object) {
innerMethod1();
innerMethod1();
innerMethod1();
}
private void innerMethod1() {
innerMethod2();
// computationally intensive operations
}
private void innerMethod2() {
// computationally intensive operations
}
}
What I've Tried
Thread.stop()
will theoretically do what I want, but not only is it deprecated but it is also only available for actual threads, while I'm working with executor tasks (which might also share threads with future tasks, for example when working in a thread pool). Nevertheless, if no better solution is found, I will convert my code to use old-fashioned Threads instead and use this method.
Another option I've tried is to mark myMethod()
and similar methods with a special "Interruptable" annotation and then use AspectJ (which I am admittedly a newbie at) for catching all method invocations there - something like:
@Before("call(* *.*(..)) && withincode(@Interruptable * *.*(..))")
public void checkInterrupt(JoinPoint thisJoinPoint) {
if (Thread.interrupted()) throw new ForcefulInterruption();
}
But withincode
isn't recursive to methods called by the matching methods, so I would have to edit this annotation into the external code.
Finally, this is similar to a previous question of mine - though a notable difference is that now I'm dealing with an external library.