I have follwoing code.
Future<Integer> future = Executor.execute(callable);
Integer i;
try {
i = future.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return MESSAGE_INT_CODE;
} catch (ExecutionException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
return i;
where ExecutionException can contain other exception say ABCException.
and my calling code is catching ABCException which is runtime exception, so if ExecutionException is occured how would I know it is because of ABCException?
ExecutionException due to some exception when my public call() method run. and call method may have some ABCException
should I write like this ?
catch (ExecutionException e) {
throw new ABCException(e.getMessage());
// TODO Auto-generated catch block
//e.printStackTrace();
}
try e.getCause() instanceof ABCException
If exception occurs during execution of call() method, ExecutorService catches it and put it in an ExecutionException. And when you call future.get(); future throws ExecutionException which contains exception from your call method. So if I understand you correctly, you code may look like this:
try {
future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if(cause instanceof ABCException) {
// cast throwable to ABCException and rethrow it
throw (ABCxception) cause;
}else {
// do something else
}
}
Related
I have functions with the same param and response type like;
public ResponseType functionA(ParamType) throws Exception1
public ResponseType functionB(ParamType) throws Exception1
and I call these functions from different places with the same repeating try/catch block. Is there any way to reduce the duplicate code?
try{
return functionA(obj);
} catch (Exception1 e) { .... }
catch (Exception2 e) { .... }
catch (Exception3 e) { .... }
try{
return functionB(obj);
} catch (Exception1 e) { .... }
catch (Exception2 e) { .... }
catch (Exception3 e) { .... }
I have tried to create a function like below, but I am getting
Exception e1 is never thrown in try block
as expected.
public ResponseType callFunction(Function<ParamType, ResponseType> function, ParamType obj) {
try{
return function.apply(obj)
}catch (Exception1 e) { .... }
catch (Exception2 e) { .... }
catch (Exception3 e) { .... }
}
The issue is that Function.apply is not declared to throw any exceptions, so it is not generally possible to throw checked exceptions from an implementation, or to catch a checked exception from it at a call site. (Ignoring unusual workarounds as mentioned in the comments.)
However, Java does not restrict lambda expressions to only be used with standard functional interfaces, so the best approach when you need to handle specific exception types is to create your own.
#FunctionalInterface
interface MyFunction {
ResponseType apply(ParamType param) throws Exception1, Exception2, Exception3;
}
This can be used in a similar way to java.util.function.Function:
public ResponseType callFunction(MyFunction function, ParamType obj) {
try{
return function.apply(obj);
}
catch (Exception1 e) { throw new RuntimeException("Exception1"); }
catch (Exception2 e) { throw new RuntimeException("Exception2"); }
catch (Exception3 e) { throw new RuntimeException("Exception3"); }
}
(Modified to throw runtime exceptions in the catch blocks so that this will compile)
The calling code is identical to any standard functional interface:
callFunction(this::functionA, obj);
callFunction(this::functionB, obj);
or, equivalently:
callFunction(param -> functionA(param), obj);
callFunction(param -> functionB(param), obj);
I wish to do this:
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
return 1;
});
f1.thenRun(() -> System.out.println(this.get()));
The last line doesn't compile. I just wish to do something inside thenRun function, and prints its own get() result inside it. I don't wish to use this return value outside calls to f1, to make code more tight.
Is there a way to do it?
Try CompletableFuture#thenAccept() where the argument is Consumer<Result>
CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {}
return 1;
});
f1.thenAccept(System.out::println);
this refer to the caller instance(object) who call the instance method, you cannot use this inside a class and refer to the declared variable f1.
You can test if the task is done then print the result else print another message, giving it 3 seconds to be sure that it will be done for example :
f1.thenRun(() -> {
try {
Thread.currentThread().sleep(3000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
if (f1.isDone())
System.out.println(f1.get());
else
System.out.println("Not Done");
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
I am able to catch RuntimeException or subclass of it with below code:
try {
//code that throws subclass of RuntimeException
throw new ChildRuntimeException("try");
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
But I am getting error with below code and not able to catch RuntimeException in Exception catch block.
try {
// code that throws subclass of Exception
throw new ChildExceptionClass("try");
} catch (ChildExceptionClass ex) {
throw new RuntimeException(ex.getMessage());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
I searched for the same type of questions but did not find a suitable answer. Can
anyone explain why the behaviour is different?
In the second example you are throwing a childRuntimeException, which is caught, but then a new runtimeException is thrown. This block has no "catch" clause, so the exception is thrown and not caught.
The second catch is relevant for the "try" block, not for the "catch" block.
What I guess you probably want to do is:
try { // code that throws subclass of Exception
throw new ChildExceptionClass("try");
} catch (ChildExceptionClass ex) {
try {
throw new RuntimeException(ex.getMessage());
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
Do you understand the difference?
In java I want to run multiple threads and get the response back from all of them.
The issue I have is if one of the threads throws an exception when I do the String temp = r.get() it drops into the catch and doesn't give me the response from the remaining threads.
Is there a way of processing all the responses regardless of whether the individual thread threw an exception?
My test code is
ExecutorService es = Executors.newFixedThreadPool(2);
List<CallTest> callList = new ArrayList<>();
callList.add(new CallTest(1));
callList.add(new CallTest(2));
callList.add(new CallTest(3));
callList.add(new CallTest(4));
try {
List<Future<String>> returns = es.invokeAll(callList);
for (Future<String> r : returns) {
String temp = r.get();
System.out.println("returned " + temp);
}
} catch (InterruptedException e) {
System.out.println("Interrupted Exception catch");
e.printStackTrace();
} catch (ExecutionException e) {
System.out.println("Execution Exception catch");
e.printStackTrace();
}
Catch exceptions inside the loop
for (Future<String> r : returns) {
try {
String temp = r.get();
System.out.println("returned " + temp);
} catch (InterruptedException e) {
System.out.println("Interrupted Exception catch");
e.printStackTrace();
} catch (ExecutionException e) {
System.out.println("Execution Exception catch");
e.printStackTrace();
}
}
Other solution:
Override afterExecute method in ThreadPoolExecutor
protected void afterExecute(Runnable r,
Throwable t)
Method invoked upon completion of execution of the given Runnable. This method is invoked by the thread that executed the task. If non-null, the Throwable is the uncaught RuntimeException or Error that caused execution to terminate abruptly.
Sample code from oracle documentation link:
class ExtendedExecutor extends ThreadPoolExecutor {
// ...
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException ce) {
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null)
System.out.println(t);
}
}
try {
throw new SomeException();
}
catch (SomeException e) {
System.out.println("reached once");
throw e;
}
catch (Exception e) {
System.out.println("reached twice");
}
This code only displays "reached once" even though the exception was thrown again inside the first catch clause. How can this be fixed in order that both catch clauses be executed?
PS: The above code was a general question I had, and I had to apply it to a much larger code with about 5 or 6 catch clauses that catch different exceptions, but in the end, at a certain point in a loop I need the exception to be thrown again.
Simply add another try catch in the catch.
try {
try {
throw new NullPointerException();
} catch (NullPointerException e) {
System.out.println("reached once");
throw e;
}
} catch (SomeOtherException ex) {}
You'll have to sorround all code that can throw an Exception with a try/catch block
try {
throw new NullPointerException();
}
catch (NullPointerException e) {
System.out.println("reached once");
try{
throw e;
}
catch (Exception ex) {
System.out.println("reached twice");
}
}