How do you throw an exception inside a lambda e.g in ifPresentOrElse of a Optional?
try {
foo.bar(baz).ifPresentOrElse(theBar -> {
// A code inside here needs to throw a custom exception so the outside can handle it
// It can't throw atm, and it is an unhandled exception here
}, () -> { response.set(notFound()); }
} catch(CustomException e) {
somethingImportantWhenExceptionIsThrown();
}
Altough not explicitly mentioned in your question, i am going to assume that you intent to throw a checked exception from ifPresentOrElse.
First, you should try to understand why you cannot throw an exception. The Consumer interface has, as Runnable, only a single abstract method, which makes it a #FunctionalInterface. From the documentation:
Note that instances of functional interfaces can be created with
lambda expressions, method references, or constructor references.
This is a reduced version of the Consumer interface:
public interface Consumer<T> {
void accept(T t); // <-- NO throws Exception
}
Alternatively, you can still use the old anonymous inner class:
Consumer<Object> consumer = new Consumer<>() {
#Override
public void accept(Object o) { // <-- NO throws Exception
// consume
}
};
Therefore, you cannot throw a checked exception from the accept method. It is not possible by design. You can, however, chose one of the following options:
Use a custom ThrowingConsumer and ThrowingOptional class, which can throw exceptions (since you declare them in their method signatures), not recommended.
Wrap the checked exception in a RuntimeException, which does not need to be declared in the method signature, and can therefore be thrown.
Rewrite your code to not use the lambda expression.
Example, for the last point:
Optional<Bar> barOpt = foo.bar(baz);
if(bar.isPresent()) {
Bar bar = barOpt.get();
try {
// code that throws checked exception
} catch(CustomException e) {
somethingImportantWhenExceptionIsThrown();
}
} else {
response.set(notFound());
}
The solution for this is to use Project Lombok:
And have the method wrapping this function annotated with SneakyThrows, as such:
#SneakyThrows
void method() {
try {
foo.bar(baz).ifPresentOrElse(theBar -> {
throw()
}, () -> { response.set(notFound()); }
} catch(CustomException e) {
somethingImportantWhenExceptionIsThrown();
}
}
You can do it with apache commons-lang3 library.
https://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/function/Failable.html
Optional.of(obj).ifPresentOrElse(Failable.asConsumer(theBar -> {
throw new Exception();
}), () -> {});
Related
Consider the following java code:
public void write(FrameConsumer fc) throws FFmpegFrameRecorder.Exception{
frameStream.forEach(n -> fc.consume(n));
}
In this case "frameStream" is a Stream of Objects that can be passed to the "consume" method, and fc is a class containing the "consume" method. Another important note is that the "consume" method throws a "FFmpegFrameRecorder.Exception", which I would like to pass on to whatever method calls "write" in the future.
However the above code does not compile, because: "Unhandled exception type FFmpegFrameRecorder.Exception Java(16777384)". Why is that?
Best regards,
CCI
EDIT:
Puting a try_catch block inside the lambda expression does not solve the problem either, hence:
public void write(FrameConsumer fc) throws FFmpegFrameRecorder.Exception{
frameStream.forEach(n -> {
try {
fc.consume(n);
} catch (FFmpegFrameRecorder.Exception e) {
throw e; //**this part does not compile**
}
});
}
(As provided by #Soumya Manna) does not compile either. The compiler still wants for the program to handle the "FFmpegFrameRecorder.Exception e" as it is thrown.
You cannot do this in lambda. You may simple write for loop and throw it or use try-catch block in lambda and throw Runtime exception there.
You could wrap the exception in a RuntimeException and then unwrap it:
public class ExceptionWrapper extends RuntimeException {
public ExceptionWrapper(Throwable cause) {
super(cause);
}
}
// ...
public void write(FrameConsumer fc) throws FFmpegFrameRecorder.Exception {
try {
frameStream.forEach(n -> {
try {
fc.consume(n));
} catch(FFmpegFrameRecorder.Exception e) {
throw new ExceptionWrapper(e);
}
});
} catch(ExceptionWrapper e) {
throw (FFmpegFrameRecorder.Exception) e.getCause();
}
}
The reason the lambda can't throw a checked exception is that java.lang.Stream#forEach's parameter (action) is of type java.util.function.Consumer, whose only non-default method, accept, does not declare any exceptions.
See also: https://docs.oracle.com/javase/tutorial/essential/exceptions/catchOrDeclare.html
I have following issue.
I'm working within a method 1 and this method 1 should return an object of a certain class.
For my return statement I call another method 2 (which of course returns an object of said class). Though this other method 2 throws an exception. How should I write my return statement in my initial method 1?
Like this?
public class testClass {
public testClass() {
}
public <T> T method1(parameter1, ...) {
if(parameter1) {
return () -> {
try {
method2(parameter1, parameter2...);
}
catch (CloneNotSupportedException ex) {
System.err.print("Error while cloning programmer");
}
};
} else {
return null;
}
}
But I guess if I do this it will only return null?
Should i put the return null after the last bracket? Or should i write this in a totally different way?
Edit. You wrote
Basically normally the exception should never be thrown
That's a perfect usecase for a RuntimeException. It's basically a transparent exception. Users of your code won't see it, but it will appear like a wild Pokemon when something extraordinary happens, and will make your application come to a stop, giving you a chance to fix it.
Your standard code flow won't be affected, and you'll avoid returning a null value.
Lambda expressions aren't allowed to throw checked Exceptions.
CloneNotSupportedException extends Exception.
Now, you have two options
Handle the Exception in-place, as you did
Propagate the Exception by wrapping it in a RuntimeException
return () -> {
try {
method2(parameter1, parameter2...);
} catch (final CloneNotSupportedException e) {
throw YourCustomRuntimeException("Error while cloning", e /* Original cause */);
}
};
This depends on the usecase, but I think CloneNotSupportedException signals a bug, which should be evident to you, developer. So let it surface.
The custom Exception just need to extend RuntimeException, and, maybe, provide additional fields to store relevant data.
YourCustomRuntimeException extends RuntimeException { ... }
Do not throw the base RuntimeException, use custom ones.
Callable throws Exception, Runnable doesn't.
Is there anything standard that looks like
#FunctionalInterface
public interface TypedBlock<E extends Exception> {
public void run() throws E;
}
No, there is no built in functionality as I know. But you can use an external library for that (and many other cool features).
You can either use JOOL, where you can use the Unchecked class for this.
The example from there page demonstrates this with an IOException
Arrays.stream(dir.listFiles()).forEach(
Unchecked.consumer(file -> { System.out.println(file.getCanonicalPath()); })
);
Another (and in my opinion better) approach would be to use a functional designed library like Functionaljava.
A good approach would be to wrap your task in a Validation to decide afterwards, if the result was successful. This could look like this:
TypedBlock<IOException> foo = ...;
// do your work
final Validation<IOException, Unit> validation = Try.f(() -> {
foo.run();
return Unit.unit(); // Unit equals nothing in functional languages
})._1();
// check if we got a failure
if (validation.isFail()) {
System.err.println("Got err " + validation.fail());
}
// check for success
if (validation.isSuccess()) {
System.out.println("All was good :-)");
}
// this will just print out a message if we got no error
validation.forEach(unit -> System.out.println("All was good"));
There is java.lang.AutoCloseable which has a ()->{} throws Exception signature, however, it is burden with a predefined semantic. So for an ad-hoc use it might be suitable but when you design an API, I recommend defining your own interface.
Note that your specialized interface could still extend Callable<Void> to be a standard interface:
interface Block<E extends Exception> extends Callable<Void>{
void run() throws E;
#Override default Void call() throws E { run(); return null; }
/** This little helper method avoids type casts when a Callable is expected */
static <T extends Exception> Block<T> make(Block<T> b) { return b; }
}
This way you can use your Block interface with existing APIs:
// Example
ExecutorService e=Executors.newSingleThreadExecutor();
try {
e.submit(Block.make(()->{ throw new IOException("test"); })).get();
} catch (InterruptedException ex) {
throw new AssertionError(ex);
} catch (ExecutionException ex) {
System.out.println("received \""+ex.getCause().getMessage()+'"');
}
e.shutdown();
Note the trick with the static method Block.make. Without it you would have to cast the lambda expression to (Block<IOException>) instead of profiting from the improved type inference. This is only necessary where a Callable is expected, for your own API where a Block is expected, you can use lambda expressions and method references directly.
Suppose I have a class and a method
class A {
void foo() throws Exception() {
...
}
}
Now I would like to call foo for each instance of A delivered by a stream like:
void bar() throws Exception {
Stream<A> as = ...
as.forEach(a -> a.foo());
}
Question: How do I properly handle the exception? The code does not compile on my machine because I do not handle the possible exceptions that can be thrown by foo(). The throws Exception of bar seems to be useless here. Why is that?
You need to wrap your method call into another one, where you do not throw checked exceptions. You can still throw anything that is a subclass of RuntimeException.
A normal wrapping idiom is something like:
private void safeFoo(final A a) {
try {
a.foo();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
(Supertype exception Exception is only used as example, never try to catch it yourself)
Then you can call it with: as.forEach(this::safeFoo).
If all you want is to invoke foo, and you prefer to propagate the exception as is (without wrapping), you can also just use Java's for loop instead (after turning the Stream into an Iterable with some trickery):
for (A a : (Iterable<A>) as::iterator) {
a.foo();
}
This is, at least, what I do in my JUnit tests, where I don't want to go through the trouble of wrapping my checked exceptions (and in fact prefer my tests to throw the unwrapped original ones)
This question may be a little old, but because I think the "right" answer here is only one way which can lead to some issues hidden Issues later in your code. Even if there is a little Controversy, Checked Exceptions exist for a reason.
The most elegant way in my opinion can you find was given by Misha here Aggregate runtime exceptions in Java 8 streams
by just performing the actions in "futures". So you can run all the working parts and collect not working Exceptions as a single one. Otherwise you could collect them all in a List and process them later.
A similar approach comes from Benji Weber. He suggests to create an own type to collect working and not working parts.
Depending on what you really want to achieve a simple mapping between the input values and Output Values occurred Exceptions may also work for you.
If you don't like any of these ways consider using (depending on the Original Exception) at least an own exception.
You might want to do one of the following:
propagate checked exception,
wrap it and propagate unchecked exception, or
catch the exception and stop propagation.
Several libraries let you do that easily. Example below is written using my NoException library.
// Propagate checked exception
as.forEach(Exceptions.sneak().consumer(A::foo));
// Wrap and propagate unchecked exception
as.forEach(Exceptions.wrap().consumer(A::foo));
as.forEach(Exceptions.wrap(MyUncheckedException::new).consumer(A::foo));
// Catch the exception and stop propagation (using logging handler for example)
as.forEach(Exceptions.log().consumer(Exceptions.sneak().consumer(A::foo)));
I suggest to use Google Guava Throwables class
propagate(Throwable throwable)
Propagates throwable as-is if it is an
instance of RuntimeException or Error, or else as a last resort, wraps
it in a RuntimeException and then propagates.**
void bar() {
Stream<A> as = ...
as.forEach(a -> {
try {
a.foo()
} catch(Exception e) {
throw Throwables.propagate(e);
}
});
}
UPDATE:
Now that it is deprecated use:
void bar() {
Stream<A> as = ...
as.forEach(a -> {
try {
a.foo()
} catch(Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
});
}
You can wrap and unwrap exceptions this way.
class A {
void foo() throws Exception {
throw new Exception();
}
};
interface Task {
void run() throws Exception;
}
static class TaskException extends RuntimeException {
private static final long serialVersionUID = 1L;
public TaskException(Exception e) {
super(e);
}
}
void bar() throws Exception {
Stream<A> as = Stream.generate(()->new A());
try {
as.forEach(a -> wrapException(() -> a.foo())); // or a::foo instead of () -> a.foo()
} catch (TaskException e) {
throw (Exception)e.getCause();
}
}
static void wrapException(Task task) {
try {
task.run();
} catch (Exception e) {
throw new TaskException(e);
}
}
More readable way:
class A {
void foo() throws MyException() {
...
}
}
Just hide it in a RuntimeException to get it past forEach()
void bar() throws MyException {
Stream<A> as = ...
try {
as.forEach(a -> {
try {
a.foo();
} catch(MyException e) {
throw new RuntimeException(e);
}
});
} catch(RuntimeException e) {
throw (MyException) e.getCause();
}
}
Although at this point I won't hold against someone if they say skip the streams and go with a for loop, unless:
you're not creating your stream using Collection.stream(), i.e. not straight forward translation to a for loop.
you're trying to use parallelstream()
Is there a way to annotate a method so all exceptions thrown are converted to runtime exception automagically?
#MagicAnnotation
// no throws clause!
void foo()
{
throw new Exception("bar")'
}
Project Lombok's #SneakyThrows is probably what you are looking for. Is not really wrapping your exception (because it can be a problem in a lot of cases), it just doesn't throw an error during compilation.
#SneakyThrows
void foo() {
throw new Exception("bar")'
}
You can do this with AspectJ. You declare a joinpoint (in this case invocation of the method foo) and 'soften' the exception.
Edit To elaborate a bit on this:
Say you have the following class Bar:
public class Bar {
public void foo() throws Exception {
}
}
...and you have a test like this:
import junit.framework.TestCase;
public class BarTest extends TestCase {
public void testTestFoo() {
new Bar().foo();
}
}
Then obviously the test is not going to compile. It will give an error:
Unhandled exception type Exception BarTest.java(line 6)
Now to overcome this with AspectJ, you write a very simple aspect:
public aspect SoftenExceptionsInTestCode {
pointcut inTestCode() : execution(void *Test.test*());
declare soft : Exception : inTestCode();
}
The aspect basically says that any code from within a Test (i.e.: a method that starts with "test" in a class that ends in "Test" and returns 'void') that throws an exception should be accepted by the AspectJ compiler. If an exception occurs, it will be wrapped and thrown as a RuntimeException by the AspectJ compiler.
Indeed, if you run this test as part of an AspectJ project from within Eclipse (with AJDT installed) then the test will succeed, whereas without the aspect it won't even compile.
No way to do that, at least for now I use workaround like this (simplified):
#SuppressWarnings({"rawtypes", "unchecked"})
public class Unchecked {
public static interface UncheckedDefinitions{
InputStream openStream();
String readLine();
...
}
private static Class proxyClass = Proxy.getProxyClass(Unchecked.class.getClassLoader(), UncheckedDefinitions.class);
public static UncheckedDefinitions unchecked(final Object target){
try{
return (UncheckedDefinitions) proxyClass.getConstructor(InvocationHandler.class).newInstance(new InvocationHandler(){
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (target instanceof Class){
return MethodUtils.invokeExactStaticMethod((Class) target, method.getName(), args);
}
return MethodUtils.invokeExactMethod(target, method.getName(), args);
}
});
}
catch(Exception e){
throw new RuntimeException(e);
}
}
}
And the usage looks like:
import static ....Unchecked.*;
...
Writer w = ...;
unchecked(w).write(str, off, len);
The trick is that interface is "never finished" and everytime I need unchecked method somewhere, I'll wrap that object into unchecked and let IDE generate method signature in interface.
Implementation is then generic (reflective and "slow" but usually fast enough)
There are some code post-processors and bytecode-weavers but this was not possible (not even aop or other jvm based language) for my current project, so this was "invented".
I think it is possible with bytecode re-engineering, customized compiler or perhaps aspect oriented programming1. In the contrary to Java, C# has only unchecked exceptions2.
May I ask why you want to suppress the checked exceptions?
1 according to Maarten Winkels this is possible.
2 and they are thinking about introducing checked ones, according to some Channel 9 videos.
Edit: For the question: It is possible in the sense that you can annotate your methods to flag them to be a candidate for checked exception suppression. Then you use some compile time or runtime trick to apply the actual suppression / wrapping.
However, as I don't see the environment around your case, wrapping an exception in these ways might confuse the clients of that method - they might not be prepared to deal with a RuntimeException. For example: the method throws an IOException and your clients catches it as FileNotFoundException to display an error dialog. However if you wrap your exception into a RuntimeException, the error dialog gets never shown and probably it kills the caller thread too. (IMHO).
The Checked exceptions are responsability of the method implementation.
Take very very carefully this fact. if you can do not use workaround artifacts like that.
You can do this in any case via use of the fact that Class.newInstance does not wrap an Exception thrown by the no-arg constructor in an InvocationTargetException; rather it throws it silently:
class ExUtil {
public static void throwSilent(Exception e) { //NOTICE NO THROWS CLAUSE
tl.set(e);
SilentThrower.class.newInstance(); //throws silently
}
private static ThreadLocal<Exception> tl = new ThreadLocal<Exception>();
private static class SilentThrower {
SilentThrower() throws Exception {
Exception e = tl.get();
tl.remove();
throw e;
}
}
}
Then you can use this utility anywhere:
ExUtil.throwSilent(new Exception());
//or
try {
ioMethod();
} catch (IOException e) { ExUtil.throwSilent(e); }
By the way, this is a really bad idea :-)
I use the completion / template system of Eclipse to wrap any block of code easily.
Here is my template :
try { // Wrapp exceptions
${line_selection}${cursor}
} catch (RuntimeException e) { // Forward runtime exception
throw e;
} catch (Exception e) { // Wrap into runtime exception
throw new RuntimeException(
"Exception wrapped in #${enclosing_method}",
e);
}