Spring Aspect fails when join point is invoked in new thread - java

I'm using Spring 3.0.5 with an Around aspect.
The #Around aspect works perfectly. The AOP expression targets the interfaces of a bunch of beans.
The aspect executes some logic before and after the invokation:
#Around(...)
public Object monitor(ProceedingJoinPoint pjp) throws Throwable {
// some code
Obj o = pjp.proceed();
// some code
}
No big deal.
Now, I'm trying to create another aspect that throws an exception if the intercepted method takes too long.
private static ExecutorService executor = Executors.newCachedThreadPool();
#Around(...)
public Object monitor(ProceedingJoinPoint pjp) throws Throwable {
Object obj = null;
Callable<Object> task = new Callable<Object>() {
public Object call() {
return pjp.proceed();
}
};
Future<Object> future = executor.submit(task);
try {
obj = future.get(timeout, TimeUnit.MILLISECONDS);
} catch (TimeoutException ex) {
...
} catch (InterruptedException e) {
// we ignore this one...
} catch (ExecutionException e) {
throw e.getCause(); // rethrow any exception raised by the invoked method
} finally {
future.cancel(true); // may or may not desire this
}
return obj;
}
When I execute the code with only this aspect applied I get the following exception:
java.lang.RuntimeException: java.lang.IllegalStateException: No
MethodInvocation found: Check that an AOP invocation is in progress,
and that the ExposeInvocationInterceptor is in the interceptor chain.
From the Spring documentation I read:
"Class ExposeInvocationInterceptor
Interceptor that exposes the current MethodInvocation as a thread-local object."
So it looks like that the target got lost because I basically start a new thread and the new thread doesn't have access to thread local. Is there a way to solve this problem or a better approach?
Thanks

The solution was quite trivial. The Aspect that checks how long a method takes must be the last in the "chain" of aspects. I have used the #Order annotation on the Aspect to make it the last one to be executed.
That did the trick.
If the Aspect is not the last to be executed, the new Thread is not able to access the ThreadLocal variable containing the ExposeInvocationInterceptor class.

You could try interrupting the current thread from another thread, if the pjp.proceed() call is amenable to interruption. E.g. your aspect looks like:
new Interrupter(Thread.currentThread()).start();
// Following call will get interrupted if it takes too long
try {
return pjp.proceed();
} catch (InterruptedException ex) {
// do something?
}
where the Interrupter class would be something like:
static class Interrupter extends Thread {
private final Thread other;
Interrupter(final Thread other) {
this.other = other;
}
#Override
public void run() {
try {
Thread.sleep(500); // or whatever your timeout is
} catch (final InterruptedException e) {
e.printStackTrace();
}
if (other.isAlive()) {
other.interrupt();
}
}
}

Related

Java Spring Async Exception Handling for methods with non void return value

I have an async function which does a particular task, sample code below,
#Async
public CompletableFuture<Boolean> foo(String value) throws Exception {
// do task
LOGGER.info("Processing completed");
return CompletableFuture.completedFuture(true);
}
Whenever any runtime exception occurs the caller function is not informed and the application runs without any errors/exceptions. This is dangerous because we will be under the false assumption that the processing is successful.
How to avoid this and make the method report error whenever any exception occurs?
To overcome this you need to add an exception try/catch block and set the exception in the completable future instance
#Async
public CompletableFuture<Boolean> foo(String value) {
CompletableFuture completableFuture = new CompletableFuture();
try{
// do task
LOGGER.info("Processing completed");
completableFuture.complete(true);
} catch(Exception e) {
completableFuture.completeExceptionally(e);
}
return completableFuture;
}
On the caller side,
CompletableFuture<Boolean> foo = service.foo(value);
foo.whenComplete((res, ex) -> {
if (ex == null) {
// success flow ...
} else {
// handle exception ...
ex.printStackTrace();
LOGGER.error("ERROR ----> " + ex.getMessage());
}
});
You can handle exceptions on the caller side using exceptionally method from CompletableFuture
CompletableFuture<Boolean> foo = service.foo(value)
.exceptionally(ex-> /* some action */ false);

How to stop main method calling sleep() method, when testing it with Junit?

I am testing a method which contain sleep in side it.What is the way to stop invoke sleep() as it makes testing slow??
public void fun(Integer timeToWait) {
TimeLimiter timeLimiter = new SimpleTimeLimiter();
try {
timeLimiter.callWithTimeout(() -> {
while (true) {
if (avrageIsAboveThanDesired) {
return true;
}
sleep(ofSeconds(REQUEST_STATUS_CHECK_INTERVAL));
}
}, timeToWait, TimeUnit.MINUTES, true);
} catch (UncheckedTimeoutException e) {
logger.error("Timed out waiting Instances to be in Running State", e);
} catch (WingsException e) {
throw e;
} catch (Exception e) {
throw new InvalidRequestException("Error while waiting Instaces to be in Running State", e);
}
}
There is no easy way for doing this. You have several options.
The easiest one would be to make the REQUEST_STATUS_CHECK_INTERVAL configurable and configure it to 0 in tests. It can be a property of the tested class.
sleep(ofSeconds(getSleepInternval()));
In the test would wold call
testedObject.setSleepInterval(0);
Second option would be to extract the sleep call into it's own class that can be mocked.
class Sleeper {
void sleep(long milisecs) {
Thread.sleep(milisecs);
}
}
In your class you would have
private Sleeper sleeper = new Sleeper(); //nd it's setter, or dependency injection
In the function
sleeper.sleep(ofSeconds(REQUEST_STATUS_CHECK_INTERVAL));
And it the test you can do
Sleeper mockedSleeper = Mockito.mock(Sleeper.class);
testedObject.setSleeper(mockedSleeper);

cancelling a future task in java [duplicate]

This question already has answers here:
Future task of ExecutorService not truly cancelling
(2 answers)
Closed 5 years ago.
I want to cancel a task submitted to ExecutorService thus allowing the corresponding thread to pick a new task from the queue.
Now this question have been answered many times on this forum.... like checking Thread.currentThread().interrupt() or catch (InterruptedException e). But if the flow of control spans across multiple methods then putting these checks makes the code clumsy. So if possible please suggest some elegant ways in java to achieve this functionality.
The problem that I'm facing is that future.cancel won't actually cancel the task. Instead it just sends an InterruptedException to the executing task and it's the task's responsibility to mark itself complete and release the thread.
So what I did is that I had to put the below block of code whenever an exception gets thrown anywhere in the execution which obviously doesn't look good !
if(e instanceof InterruptedException) {
throw e;
}
So, how to achieve this functionality in following code snippet:
public class MonitoringInParallelExp {
public static void main(String[] args) throws InterruptedException {
MyClass1 myClass1 = new MyClass1();
ExecutorService service = Executors.newFixedThreadPool(1);
Future<String> future1 = service.submit(myClass1);
Thread.sleep(2000);
System.out.println("calling cancel in Main");
future1.cancel(true);
System.out.println("finally called cancel in Main");
service.shutdown();
}
}
class MyClass1 implements Callable<String> {
#Override
public String call() throws Exception {
try{
MyClass2 myClass2 = new MyClass2();
myClass2.method2();
} catch (Exception e){
if(e instanceof InterruptedException) {
System.out.println("call:"+"e instanceof InterruptedException="+"true");
throw e;
}
System.out.println("Got exception in method1. " + e);
}
System.out.println("returning Myclass1.method1.exit");
return "Myclass1.method1.exit";
}
}
class MyClass2 {
public void method2() throws Exception{
try{
MyClass3 myClass3 = new MyClass3();
myClass3.method3();
} catch (Exception e){
if(e instanceof InterruptedException) {
System.out.println("method2:"+"e instanceof InterruptedException="+"true");
throw e;
}
System.out.println("Got exception in method2. " + e);
// in case the exception isn't InterruptedExceptionm, do some work here
}
}
}
class MyClass3 {
public void method3() throws Exception{
try{
Thread.sleep(10000);
} catch (Exception e){
if(e instanceof InterruptedException) {
System.out.println("method3:"+"e instanceof InterruptedException="+"true");
throw e;
}
System.out.println("Got exception in method3. " + e);
throw new MyException();
}
}
}
class MyException extends Exception {
}
It does not matter if you interrupt the Callable or not, because at that point it's already too late
try{
MyClass2 myClass2 = new MyClass2();
myClass2.method2();
} catch (Exception e){
Your call to future1.cancel(true); after Thread.sleep(2000) does not actually cancel the ongoing task (in this case your method2 call) it only means that it should have been cancelled before it started.
The docs point that out
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)
Attempts to cancel execution of this task. This attempt will fail if the task has already completed, has already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
If you want to cancel a ongoing task you want to use a volatile boolean flag or something similiar.

How do I call some blocking method with a timeout in Java?

Is there a standard nice way to call a blocking method with a timeout in Java? I want to be able to do:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
if that makes sense.
Thanks.
You could use an Executor:
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
return something.blockingMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// handle the timeout
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
future.cancel(true); // may or may not desire this
}
If the future.get doesn't return in 5 seconds, it throws a TimeoutException. The timeout can be configured in seconds, minutes, milliseconds or any unit available as a constant in TimeUnit.
See the JavaDoc for more detail.
You could wrap the call in a FutureTask and use the timeout version of get().
See http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html
See also Guava's TimeLimiter which uses an Executor behind the scenes.
It's really great that people try to implement this in so many ways. But the truth is, there is NO way.
Most developers would try to put the blocking call in a different thread and have a future or some timer. BUT there is no way in Java to stop a thread externally, let alone a few very specific cases like the Thread.sleep() and Lock.lockInterruptibly() methods that explicitly handle thread interruption.
So really you have only 3 generic options:
Put your blocking call on a new thread and if the time expires you just move on, leaving that thread hanging. In that case you should make sure the thread is set to be a Daemon thread. This way the thread will not stop your application from terminating.
Use non blocking Java APIs. So for network for example, use NIO2 and use the non blocking methods. For reading from the console use Scanner.hasNext() before blocking etc.
If your blocking call is not an IO, but your logic, then you can repeatedly check for Thread.isInterrupted() to check if it was interrupted externally, and have another thread call thread.interrupt() on the blocking thread
This course about concurrency https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
really walks through those fundamentals if you really want to understand how it works in Java. It actually talks about those specific limitations and scenarios, and how to go about them in one of the lectures.
I personally try to program without using blocking calls as much as possible. There are toolkits like Vert.x for example that make it really easy and performant to do IO and no IO operations asynchronously and in a non blocking way.
I hope it helps
There is also an AspectJ solution for that with jcabi-aspects library.
#Timeable(limit = 30, unit = TimeUnit.MINUTES)
public Soup cookSoup() {
// Cook soup, but for no more than 30 minutes (throw and exception if it takes any longer
}
It can't get more succinct, but you have to depend on AspectJ and introduce it in your build lifecycle, of course.
There is an article explaining it further: Limit Java Method Execution Time
I'm giving you here the complete code. In place of the method I'm calling, you can use your method:
public class NewTimeout {
public String simpleMethod() {
return "simple method";
}
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Callable<Object> task = new Callable<Object>() {
public Object call() throws InterruptedException {
Thread.sleep(1100);
return new NewTimeout().simpleMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(1, TimeUnit.SECONDS);
System.out.println(result);
} catch (TimeoutException ex) {
System.out.println("Timeout............Timeout...........");
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
executor.shutdown(); // may or may not desire this
}
}
}
Thread thread = new Thread(new Runnable() {
public void run() {
something.blockingMethod();
}
});
thread.start();
thread.join(2000);
if (thread.isAlive()) {
thread.stop();
}
Note, that stop is deprecated, better alternative is to set some volatile boolean flag, inside blockingMethod() check it and exit, like this:
import org.junit.*;
import java.util.*;
import junit.framework.TestCase;
public class ThreadTest extends TestCase {
static class Something implements Runnable {
private volatile boolean stopRequested;
private final int steps;
private final long waitPerStep;
public Something(int steps, long waitPerStep) {
this.steps = steps;
this.waitPerStep = waitPerStep;
}
#Override
public void run() {
blockingMethod();
}
public void blockingMethod() {
try {
for (int i = 0; i < steps && !stopRequested; i++) {
doALittleBit();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void doALittleBit() throws InterruptedException {
Thread.sleep(waitPerStep);
}
public void setStopRequested(boolean stopRequested) {
this.stopRequested = stopRequested;
}
}
#Test
public void test() throws InterruptedException {
final Something somethingRunnable = new Something(5, 1000);
Thread thread = new Thread(somethingRunnable);
thread.start();
thread.join(2000);
if (thread.isAlive()) {
somethingRunnable.setStopRequested(true);
thread.join(2000);
assertFalse(thread.isAlive());
} else {
fail("Exptected to be alive (5 * 1000 > 2000)");
}
}
}
You need a circuit breaker implementation like the one present in the failsafe project on GitHub.
Try this. More simple solution. Guarantees that if block didn't execute within the time limit. the process will terminate and throws an exception.
public class TimeoutBlock {
private final long timeoutMilliSeconds;
private long timeoutInteval=100;
public TimeoutBlock(long timeoutMilliSeconds){
this.timeoutMilliSeconds=timeoutMilliSeconds;
}
public void addBlock(Runnable runnable) throws Throwable{
long collectIntervals=0;
Thread timeoutWorker=new Thread(runnable);
timeoutWorker.start();
do{
if(collectIntervals>=this.timeoutMilliSeconds){
timeoutWorker.stop();
throw new Exception("<<<<<<<<<<****>>>>>>>>>>> Timeout Block Execution Time Exceeded In "+timeoutMilliSeconds+" Milli Seconds. Thread Block Terminated.");
}
collectIntervals+=timeoutInteval;
Thread.sleep(timeoutInteval);
}while(timeoutWorker.isAlive());
System.out.println("<<<<<<<<<<####>>>>>>>>>>> Timeout Block Executed Within "+collectIntervals+" Milli Seconds.");
}
/**
* #return the timeoutInteval
*/
public long getTimeoutInteval() {
return timeoutInteval;
}
/**
* #param timeoutInteval the timeoutInteval to set
*/
public void setTimeoutInteval(long timeoutInteval) {
this.timeoutInteval = timeoutInteval;
}
}
example :
try {
TimeoutBlock timeoutBlock = new TimeoutBlock(10 * 60 * 1000);//set timeout in milliseconds
Runnable block=new Runnable() {
#Override
public void run() {
//TO DO write block of code
}
};
timeoutBlock.addBlock(block);// execute the runnable block
} catch (Throwable e) {
//catch the exception here . Which is block didn't execute within the time limit
}
In special case of a blocking queue:
Generic java.util.concurrent.SynchronousQueue has a poll method with timeout parameter.
Assume blockingMethod just sleep for some millis:
public void blockingMethod(Object input) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
My solution is to use wait() and synchronized like this:
public void blockingMethod(final Object input, long millis) {
final Object lock = new Object();
new Thread(new Runnable() {
#Override
public void run() {
blockingMethod(input);
synchronized (lock) {
lock.notify();
}
}
}).start();
synchronized (lock) {
try {
// Wait for specific millis and release the lock.
// If blockingMethod is done during waiting time, it will wake
// me up and give me the lock, and I will finish directly.
// Otherwise, when the waiting time is over and the
// blockingMethod is still
// running, I will reacquire the lock and finish.
lock.wait(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
So u can replace
something.blockingMethod(input)
to
something.blockingMethod(input, 2000)
Hope it helps.

Output from anonymous classes?

How can I get output from Java anonymous classes? In .Net I would use closures.
executor = Executors.newSingleThreadExecutor();
final Runnable runnable = new Runnable() {
public Exception exception;
#Override
public void run() {
try {
doSomething();
}
catch (Exception exception) {
// I'd like to report this exception, but how?
// the exception member is not readable from outside the class (without reflection...)
this.exception = exception;
}
}
};
executor.submit(runnable);
// Here I'd like to check if there was an exception
The Executor interface offers no way to do this. However, when you call newSingleThreadExecutor() you will get an ExecutorService which contains functionality for that.
Calling ExecutorService.submit() returns an instance of Future<?>, which you can use to get the result value of the computation.
If the execution resulted in an exception, calling get will cause an ExecutionException to be thrown.
To obtain an exception from a task run on an executor you want to use Callable instead of Runnable.
The call() method of Callable can throw checked exceptions. When you call get() on your Future instance it will throw an ExecutionException if your call() method threw a checked exception. You can then access the underlying checked exception by calling getCause() on the ExecutionException.
Hackish.... but, you could have a static variable/method that the Runnable calls to report the exception
public class Driver {
static Exception exec;
static final Runnable runnable = new Runnable() {
public Exception exception;
public void run() {
try {
throw new Exception("asdf");
}
catch (Exception exception) {
exec = exception;
}
}
};
public static void main(String[] args) throws Exception{
ExecutorService e = Executors.newSingleThreadExecutor();
e.submit(runnable);
e.shutdown();
while(e.isShutdown()==false){
Thread.sleep(2000);
}
System.out.println(exec);
}
You could wrap your thrown exception in a RuntimeException and put your executor.submit() call in a try/catch block:
executor = Executors.newSingleThreadExecutor();
final Runnable runnable = new Runnable() {
#Override
public void run() {
try {
doSomething();
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
};
try{
executor.submit(runnable);
} catch (Throwable t) {
Throwable cause = t.getCause();
//do what you want with the cause
}
If you declare the exception to be final, the anonymous class will be able to store the value there, and you can check the variable when the run() is done.
Edit to add: Sorry, I meant to make it a final array of one exception. Idea does this automatically for me, so I often forget about the extra redirection.
final Exception[] except;

Categories