Related
I would like to generalize the following pattern:
setChangeListener = c -> {
try {
// do something dangerous
} catch (final IOException e) {
logger.error(e.getLocalizedMessage(), e);
}
};
I would like to use it like this:
errorLoggingSetChangeListener = c -> {
// do something dangerous
};
I was thinking about this:
public class ErrorLoggingSetChangeListener<T> implements SetChangeListener<T> {
private static final Logger logger = Logger.getLogger(ErrorLoggingSetChangeListener.class);
private final SetChangeListener<T> delegate;
#Override
public void onChanged(final SetChangeListener.Change<? extends T> change) {
try {
delegate.onChanged(change);
} catch (final Exception e) {
if (logger.isEnabledFor(Level.ERROR)) {
logger.error(e.getLocalizedMessage(), e);
}
}
}
public ErrorLoggingSetChangeListener(final SetChangeListener<T> delegate) {
super();
this.delegate = delegate;
}
}
But that is not possible, since ErrorLoggingSetChangeListener is not a Functional interface.
Any chance to convert this class to an Functional Interface?
This does not compile:
public interface ErrorLoggingSetChangeListener<T> extends SetChangeListener<T> {
static final Logger logger = Logger.getLogger(ErrorLoggingSetChangeListener.class);
#Override
default void onChanged(final SetChangeListener.Change<? extends T> change) {
try {
SetChangeListener.super.onChanged(change);
} catch (final Exception e) {
if (logger.isEnabledFor(Level.ERROR)) {
logger.error(e.getLocalizedMessage(), e);
}
}
}
}
This does also not compile:
errorLoggingSetChangeListener = new ErrorLoggingSetChangeListener<>(c -> {
throw new IOException();
});
The error message is
Unhandled exception [..]
.
This is similar to #JonnyAW's solution, but combines both classes into a single interface:
import javafx.collections.SetChangeListener;
#FunctionalInterface
public interface ErrorLoggingSetChangeListener<E> extends SetChangeListener<E> {
public void delegate(Change<? extends E> change) throws Exception ;
#Override
public default void onChanged(Change<? extends E> change) {
try {
delegate(change);
} catch (Exception exc) {
// just do a System.out.println here to demo we reach this block:
System.out.println("Custom error handling...");
exc.printStackTrace();
}
}
}
And here's a demo of using this:
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
public class Test {
public static void main(String[] args) {
ObservableSet<String> set = FXCollections.observableSet();
ErrorLoggingSetChangeListener<String> listener = c -> {
if (c.wasAdded()) {
int i = Integer.parseInt(c.getElementAdded());
System.out.println("Value added: "+i);
}
};
set.addListener(listener);
set.add("42");
set.add("What do you get when you multiply 6 by 9?");
}
}
which generates the expected output:
Value added: 42
Custom error handling...
java.lang.NumberFormatException: For input string: "What do you get when you multiply 6 by 9?"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at Test.lambda$0(Test.java:10)
at ErrorLoggingSetChangeListener.onChanged(ErrorLoggingSetChangeListener.java:12)
at com.sun.javafx.collections.SetListenerHelper$SingleChange.fireValueChangedEvent(SetListenerHelper.java:163)
at com.sun.javafx.collections.SetListenerHelper.fireValueChangedEvent(SetListenerHelper.java:72)
at com.sun.javafx.collections.ObservableSetWrapper.callObservers(ObservableSetWrapper.java:128)
at com.sun.javafx.collections.ObservableSetWrapper.add(ObservableSetWrapper.java:269)
at Test.main(Test.java:17)
here is my implementation, that will compile:
ErrorLoggingSetChangeListener:
import javafx.collections.SetChangeListener;
public class ErrorLoggingSetChangeListener<T> implements SetChangeListener<T> {
private DangerousInterface<T> delegate;
public ErrorLoggingSetChangeListener(DangerousInterface<T> delegate) {
super();
this.delegate = delegate;
}
#Override
public void onChanged(Change<? extends T> change) {
try {
this.delegate.delegate(change);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
DangerousInterface:
public interface DangerousInterface<T> {
public void delegate(Change<? extends T> change) throws Exception;
}
Main:
SetChangeListener<String> listener = new ErrorLoggingSetChangeListener<>((test) -> {
//no errors here now
throw new Exception();
});
I got definitely no compile errors
EDIT: ok, I got the Problem, you need a new Interface that can actually throw something, now you can wrap it in onChanged
Okay, the title is maybe hard to understand. I didn't find something correct.
So, basically I'm using Java 8 functions to create a Retryable API. I wanted an easy implementation of these interfaces, so I created an of(...) method in each implementation of the Retryable interface where we can use lambda expressions, instead of creating manually an anonymous class.
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public interface Retryable<T, R> extends Function<T, R>{
void retrying(Exception e);
void skipping(Exception e);
int trials();
#Override
default R apply(T t) {
int trial = 0;
while (true) {
trial++;
try {
return action(t);
} catch (Exception e) {
if (trial < trials()) {
retrying(e);
} else {
skipping(e);
return null;
}
}
}
}
R action(T input) throws Exception;
interface RunnableRetryable extends Retryable<Void, Void> {
static RunnableRetryable of(Consumer<Exception> retrying, Consumer<Exception> skipping, int trials, CheckedRunnable runnable) {
return new RunnableRetryable() {
#Override
public void retrying(Exception e) {
retrying.accept(e);
}
#Override
public void skipping(Exception e) {
skipping.accept(e);
}
#Override
public int trials() {
return trials;
}
#Override
public Void action(Void v) throws Exception {
runnable.tryRun();
return null;
}
};
}
#FunctionalInterface
interface CheckedRunnable extends Runnable {
void tryRun() throws Exception;
#Override
default void run() {
try {
tryRun();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
interface ConsumerRetryable<T> extends Retryable<T, Void> {
static <T> ConsumerRetryable of(Consumer<Exception> retrying, Consumer<Exception> skipping, int trials, CheckedConsumer<T> consumer) {
return new ConsumerRetryable<T>() {
#Override
public void retrying(Exception e) {
retrying.accept(e);
}
#Override
public void skipping(Exception e) {
skipping.accept(e);
}
#Override
public int trials() {
return trials;
}
#Override
public Void action(T t) throws Exception {
consumer.tryAccept(t);
return null;
}
};
}
#FunctionalInterface
interface CheckedConsumer<T> extends Consumer<T> {
void tryAccept(T t) throws Exception;
#Override
default void accept(T t) {
try {
tryAccept(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
interface SupplierRetryable<T> extends Retryable<Void, T> {
static <T> SupplierRetryable of(Consumer<Exception> retrying, Consumer<Exception> skipping, int trials, CheckedSupplier<T> supplier) {
return new SupplierRetryable<T>() {
#Override
public void retrying(Exception e) {
retrying.accept(e);
}
#Override
public void skipping(Exception e) {
skipping.accept(e);
}
#Override
public int trials() {
return trials;
}
#Override
public T action(Void v) throws Exception {
return supplier.tryGet();
}
};
}
#FunctionalInterface
interface CheckedSupplier<T> extends Supplier<T> {
T tryGet() throws Exception;
#Override
default T get() {
try {
return tryGet();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
interface FunctionRetryable<T, R> extends Retryable<T, R> {
static <T, R> FunctionRetryable of(Consumer<Exception> retrying, Consumer<Exception> skipping, int trials, CheckedFunction<T, R> function) {
return new FunctionRetryable<T, R>() {
#Override
public void retrying(Exception e) {
retrying.accept(e);
}
#Override
public void skipping(Exception e) {
skipping.accept(e);
}
#Override
public int trials() {
return trials;
}
#Override
public R action(T t) throws Exception {
return function.tryApply(t);
}
};
}
#FunctionalInterface
interface CheckedFunction<T, R> extends Function<T, R> {
R tryApply(T t) throws Exception;
#Override
default R apply(T t) {
try {
return tryApply(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
}
But as you can see, there's a lot of duplicate code in every of(...) methods. I could create a kind of "constructor" (that's not the correct word, because interfaces can't have a constructor) in the Retryable interface, but I don't know how. Does someone have an idea ?
The main problem is your API explosion. All these nested interfaces extending Retryable do not add any functionality, but require the user of this code to deal with them, once they are part of the API. Further, they are the cause of this code duplication, as each of these redundant interfaces requires its own implementation, whereas all implementations are basically doing the same.
After removing these obsolete types, you can simply implement the operations as delegation:
public interface Retryable<T, R> extends Function<T, R>{
void retrying(Exception e);
void skipping(Exception e);
int trials();
#Override default R apply(T t) {
try { return action(t); }
catch(Exception e) {
for(int trial = 1; trial < trials(); trial++) {
retrying(e);
try { return action(t); } catch (Exception next) { e=next; }
}
skipping(e);
return null;
}
}
R action(T input) throws Exception;
public static Retryable<Void, Void> of(Consumer<Exception> retrying,
Consumer<Exception> skipping, int trials, CheckedRunnable runnable) {
return of(retrying, skipping, trials, x -> { runnable.tryRun(); return null; });
}
#FunctionalInterface interface CheckedRunnable extends Runnable {
void tryRun() throws Exception;
#Override default void run() {
try { tryRun(); } catch (Exception e) { throw new RuntimeException(e); }
}
}
public static <T> Retryable<T, Void> of(Consumer<Exception> retrying,
Consumer<Exception> skipping, int trials, CheckedConsumer<T> consumer) {
return of(retrying, skipping, trials,
value -> { consumer.tryAccept(value); return null; });
}
#FunctionalInterface interface CheckedConsumer<T> extends Consumer<T> {
void tryAccept(T t) throws Exception;
#Override default void accept(T t) {
try { tryAccept(t); } catch (Exception e) { throw new RuntimeException(e); }
}
}
public static <T> Retryable<Void, T> of(Consumer<Exception> retrying,
Consumer<Exception> skipping, int trials, CheckedSupplier<T> supplier) {
return of(retrying, skipping, trials, voidArg -> { return supplier.tryGet(); });
}
#FunctionalInterface interface CheckedSupplier<T> extends Supplier<T> {
T tryGet() throws Exception;
#Override default T get() {
try { return tryGet(); }
catch (Exception e) { throw new RuntimeException(e); }
}
}
public static <T, R> Retryable<T, R> of(Consumer<Exception> retrying,
Consumer<Exception> skipping, int trials, CheckedFunction<T, R> function) {
return new Retryable<T, R>() {
#Override public void retrying(Exception e) { retrying.accept(e); }
#Override public void skipping(Exception e) { skipping.accept(e); }
#Override public int trials() { return trials; }
#Override public R action(T t) throws Exception {
return function.tryApply(t);
}
};
}
#FunctionalInterface interface CheckedFunction<T, R> extends Function<T, R> {
R tryApply(T t) throws Exception;
#Override default R apply(T t) {
try { return tryApply(t); }
catch (Exception e) { throw new RuntimeException(e); }
}
}
}
There is only one implementation class needed, which has to be able to deal with an argument and a return value, the others can simply delegate to it using an adapter function, doing either, dropping the argument or returning null, or both.
For most use cases, the shape of the lambda expression is appropriate to select the right method, e.g.
Retryable<Void,Void> r = Retryable.of(e -> {}, e -> {}, 3, () -> {});
Retryable<Void,String> s = Retryable.of(e -> {}, e -> {}, 3, () -> "foo");
Retryable<Integer,Integer> f = Retryable.of(e -> {}, e -> {}, 3, i -> i/0);
but sometimes, a little hint is required:
// braces required to disambiguate between Function and Consumer
Retryable<String,Void> c = Retryable.of(e->{}, e ->{}, 3,
str -> { System.out.println(str); });
It looks like you can factor some of this out in to a (possibly package-private) abstract class:
abstract class AbstractRetryable<T, R> implements Retryable<T, R> {
private final Consumer<Exception> retrying;
private final Consumer<Exception> skipping;
private final int trials;
AbstractRetryable(Consumer<Exception> retrying,
Consumer<Exception> skipping,
int trials) {
this.retrying = Objects.requireNonNull(retrying, "retrying");
this.skipping = Objects.requireNonNull(skipping, "skipping");
this.trials = trials;
}
#Override
public void retrying(Exception x) {
retrying.accept(x);
}
#Override
public void skipping(Exception x) {
skipping.accept(x);
}
#Override
public int trials() {
return trials;
}
}
The only issue with this is that you're using subinterfaces, so you can't create an anonymous class which both extends the abstract class and implements the subinterface.
You could then write more (again, possibly package-private) subclasses:
final class RunnableRetryableImpl
extends AbstractRetryable<Void, Void>
implements RunnableRetryable {
private final CheckedRunnable runnable;
RunnableRetryableImpl(Consumer<Exception> retrying,
Consumer<Exception> skipping,
int trials,
CheckedRunnable runnable) {
super(retrying, skipping, trials);
this.runnable = Objects.requireNonNull(runnable, "runnable");
}
#Override
public Void apply(Void ignored) {
try {
runnable.tryRun();
} catch (Exception x) {
// BTW I would consider doing this.
if (x instanceof RuntimeException)
throw (RuntimeException) x;
// I would also probably write a class like:
// class RethrownException extends RuntimeException {
// RethrownException(Exception cause) {
// super(cause);
// }
// }
// This way the caller can catch a specific type if
// they want to.
// (See e.g. java.io.UncheckedIOException)
throw new RuntimeException(x);
}
return null;
}
}
Or you could reduce the line count by using local classes:
static RunnableRetryable of(Consumer<Exception> retrying,
Consumer<Exception> skipping,
int trials,
CheckedRunnable runnable) {
Objects.requireNonNull(runnable, "runnable");
final class RunnableRetryableImpl
extends AbstractRetryable<Void, Void>
implements RunnableRetryable {
RunnableRetryable() {
// Avoid explicitly declaring parameters
// and passing arguments.
super(retrying, skipping, trials);
}
#Override
public Void apply(Void ignored) {
try {
runnable.tryRun();
} catch (Exception x) {
if (x instanceof RuntimeException)
throw (RuntimeException) x;
throw new RuntimeException(x);
}
return null;
}
}
return new RunnableRetryableImpl();
}
Personally, I think I would just write package-private implementations instead of the local classes but it certainly requires a fair amount of boiler-plate code.
Also, as a side note, when you are writing factories that return anonymous classes, you should use requireNonNull inside the method itself (as I did in my example of method). This is so that if null is passed to the method, the method throws the NPE instead of e.g. some call to retrying or skipping throwing the NPE some time later.
I know how to create a reference to a method that has a String parameter and returns an int, it's:
Function<String, Integer>
However, this doesn't work if the function throws an exception, say it's defined as:
Integer myMethod(String s) throws IOException
How would I define this reference?
You'll need to do one of the following.
If it's your code, then define your own functional interface that declares the checked exception:
#FunctionalInterface
public interface CheckedFunction<T, R> {
R apply(T t) throws IOException;
}
and use it:
void foo (CheckedFunction f) { ... }
Otherwise, wrap Integer myMethod(String s) in a method that doesn't declare a checked exception:
public Integer myWrappedMethod(String s) {
try {
return myMethod(s);
}
catch(IOException e) {
throw new UncheckedIOException(e);
}
}
and then:
Function<String, Integer> f = (String t) -> myWrappedMethod(t);
or:
Function<String, Integer> f =
(String t) -> {
try {
return myMethod(t);
}
catch(IOException e) {
throw new UncheckedIOException(e);
}
};
You can actually extend Consumer (and Function etc.) with a new interface that handles exceptions -- using Java 8's default methods!
Consider this interface (extends Consumer):
#FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {
#Override
default void accept(final T elem) {
try {
acceptThrows(elem);
} catch (final Exception e) {
// Implement your own exception handling logic here..
// For example:
System.out.println("handling an exception...");
// Or ...
throw new RuntimeException(e);
}
}
void acceptThrows(T elem) throws Exception;
}
Then, for example, if you have a list:
final List<String> list = Arrays.asList("A", "B", "C");
If you want to consume it (eg. with forEach) with some code that throws exceptions, you would traditionally have set up a try/catch block:
final Consumer<String> consumer = aps -> {
try {
// maybe some other code here...
throw new Exception("asdas");
} catch (final Exception ex) {
System.out.println("handling an exception...");
}
};
list.forEach(consumer);
But with this new interface, you can instantiate it with a lambda expression and the compiler will not complain:
final ThrowingConsumer<String> throwingConsumer = aps -> {
// maybe some other code here...
throw new Exception("asdas");
};
list.forEach(throwingConsumer);
Or even just cast it to be more succinct!:
list.forEach((ThrowingConsumer<String>) aps -> {
// maybe some other code here...
throw new Exception("asda");
});
Update
Looks like there's a very nice utility library part of Durian called Errors which can be used to solve this problem with a lot more flexibility. For example, in my implementation above I've explicitly defined the error handling policy (System.out... or throw RuntimeException), whereas Durian's Errors allow you to apply a policy on the fly via a large suite of utility methods. Thanks for sharing it, #NedTwigg!.
Sample usage:
list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));
I think Durian's Errors class combines many of the pros of the various suggestions above.
Wrap a throwing function to a standard Java 8 functional interface.
Easily specify various policies for handling errors
When wrapping a method that returns a value, there is an important distinction between specifying a default value or rethrowing a RuntimeException.
Throwing versions of Java 8's functional interfaces
Similar to fge's answer
Standard interfaces for throwing specific exceptions
Which addresses Zoltán's concern
To include Durian in your project, you can either:
grab it from jcenter or maven central at com.diffplug.durian:durian:3.3.0
or just copy paste just two small classes into your code: Throwing.java and Errors.java
This is not specific to Java 8. You are trying to compile something equivalent to:
interface I {
void m();
}
class C implements I {
public void m() throws Exception {} //can't compile
}
Disclaimer: I haven't used Java 8 yet, only read about it.
Function<String, Integer> doesn't throw IOException, so you can't put any code in it that throws IOException. If you're calling a method that expects a Function<String, Integer>, then the lambda that you pass to that method can't throw IOException, period. You can either write a lambda like this (I think this is the lambda syntax, not sure):
(String s) -> {
try {
return myMethod(s);
} catch (IOException ex) {
throw new RuntimeException(ex);
// (Or do something else with it...)
}
}
Or, if the method you're passing the lambda to is one you wrote yourself, you can define a new functional interface and use that as the parameter type instead of Function<String, Integer>:
public interface FunctionThatThrowsIOException<I, O> {
O apply(I input) throws IOException;
}
If you don't mind to use a 3rd party lib (Vavr) you could write
CheckedFunction1<String, Integer> f = this::myMethod;
It also has the so-called Try monad which handles errors:
Try(() -> f.apply("test")) // results in a Success(Integer) or Failure(Throwable)
.map(i -> ...) // only executed on Success
...
Please read more here.
Disclaimer: I'm the creator of Vavr.
Sneaky throw idiom enables bypassing CheckedException of Lambda expression. Wrapping a CheckedException in a RuntimeException is not good for strict error handling.
It can be used as a Consumer function used in a Java collection.
Here is a simple and improved version of jib's answer.
import static Throwing.rethrow;
#Test
public void testRethrow() {
thrown.expect(IOException.class);
thrown.expectMessage("i=3");
Arrays.asList(1, 2, 3).forEach(rethrow(e -> {
int i = e.intValue();
if (i == 3) {
throw new IOException("i=" + i);
}
}));
}
This just wrapps the lambda in a rethrow. It makes CheckedException rethrow any Exception that was thrown in your lambda.
public final class Throwing {
private Throwing() {}
#Nonnull
public static <T> Consumer<T> rethrow(#Nonnull final ThrowingConsumer<T> consumer) {
return consumer;
}
/**
* The compiler sees the signature with the throws T inferred to a RuntimeException type, so it
* allows the unchecked exception to propagate.
*
* http://www.baeldung.com/java-sneaky-throws
*/
#SuppressWarnings("unchecked")
#Nonnull
public static <E extends Throwable> void sneakyThrow(#Nonnull Throwable ex) throws E {
throw (E) ex;
}
}
Find a complete code and unit tests here.
You could however create your own FunctionalInterface that throws as below..
#FunctionalInterface
public interface UseInstance<T, X extends Throwable> {
void accept(T instance) throws X;
}
then implement it using Lambdas or references as shown below.
import java.io.FileWriter;
import java.io.IOException;
//lambda expressions and the execute around method (EAM) pattern to
//manage resources
public class FileWriterEAM {
private final FileWriter writer;
private FileWriterEAM(final String fileName) throws IOException {
writer = new FileWriter(fileName);
}
private void close() throws IOException {
System.out.println("close called automatically...");
writer.close();
}
public void writeStuff(final String message) throws IOException {
writer.write(message);
}
//...
public static void use(final String fileName, final UseInstance<FileWriterEAM, IOException> block) throws IOException {
final FileWriterEAM writerEAM = new FileWriterEAM(fileName);
try {
block.accept(writerEAM);
} finally {
writerEAM.close();
}
}
public static void main(final String[] args) throws IOException {
FileWriterEAM.use("eam.txt", writerEAM -> writerEAM.writeStuff("sweet"));
FileWriterEAM.use("eam2.txt", writerEAM -> {
writerEAM.writeStuff("how");
writerEAM.writeStuff("sweet");
});
FileWriterEAM.use("eam3.txt", FileWriterEAM::writeIt);
}
void writeIt() throws IOException{
this.writeStuff("How ");
this.writeStuff("sweet ");
this.writeStuff("it is");
}
}
You can use unthrow wrapper
Function<String, Integer> func1 = s -> Unthrow.wrap(() -> myMethod(s));
or
Function<String, Integer> func2 = s1 -> Unthrow.wrap((s2) -> myMethod(s2), s1);
You can.
Extending #marcg 's UtilException and adding generic <E extends Exception> where necessary: this way, the compiler will force you again to add throw clauses and everything's as if you could throw checked exceptions natively on java 8's streams.
public final class LambdaExceptionUtil {
#FunctionalInterface
public interface Function_WithExceptions<T, R, E extends Exception> {
R apply(T t) throws E;
}
/**
* .map(rethrowFunction(name -> Class.forName(name))) or .map(rethrowFunction(Class::forName))
*/
public static <T, R, E extends Exception> Function<T, R> rethrowFunction(Function_WithExceptions<T, R, E> function) throws E {
return t -> {
try {
return function.apply(t);
} catch (Exception exception) {
throwActualException(exception);
return null;
}
};
}
#SuppressWarnings("unchecked")
private static <E extends Exception> void throwActualException(Exception exception) throws E {
throw (E) exception;
}
}
public class LambdaExceptionUtilTest {
#Test
public void testFunction() throws MyTestException {
List<Integer> sizes = Stream.of("ciao", "hello").<Integer>map(rethrowFunction(s -> transform(s))).collect(toList());
assertEquals(2, sizes.size());
assertEquals(4, sizes.get(0).intValue());
assertEquals(5, sizes.get(1).intValue());
}
private Integer transform(String value) throws MyTestException {
if(value==null) {
throw new MyTestException();
}
return value.length();
}
private static class MyTestException extends Exception { }
}
I had this problem with Class.forName and Class.newInstance inside a lambda, so I just did:
public Object uncheckedNewInstanceForName (String name) {
try {
return Class.forName(name).newInstance();
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
Inside the lambda, instead of calling Class.forName("myClass").newInstance() I just called uncheckedNewInstanceForName ("myClass")
Create a custom return type that will propagate the checked exception. This is an alternative to creating a new interface that mirrors the existing functional interface with the slight modification of a "throws exception" on the functional interface's method.
Definition
CheckedValueSupplier
public static interface CheckedValueSupplier<V> {
public V get () throws Exception;
}
CheckedValue
public class CheckedValue<V> {
private final V v;
private final Optional<Exception> opt;
public Value (V v) {
this.v = v;
}
public Value (Exception e) {
this.opt = Optional.of(e);
}
public V get () throws Exception {
if (opt.isPresent()) {
throw opt.get();
}
return v;
}
public Optional<Exception> getException () {
return opt;
}
public static <T> CheckedValue<T> returns (T t) {
return new CheckedValue<T>(t);
}
public static <T> CheckedValue<T> rethrows (Exception e) {
return new CheckedValue<T>(e);
}
public static <V> CheckedValue<V> from (CheckedValueSupplier<V> sup) {
try {
return CheckedValue.returns(sup.get());
} catch (Exception e) {
return Result.rethrows(e);
}
}
public static <V> CheckedValue<V> escalates (CheckedValueSupplier<V> sup) {
try {
return CheckedValue.returns(sup.get());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Usage
// Don't use this pattern with FileReader, it's meant to be an
// example. FileReader is a Closeable resource and as such should
// be managed in a try-with-resources block or in another safe
// manner that will make sure it is closed properly.
// This will not compile as the FileReader constructor throws
// an IOException.
Function<String, FileReader> sToFr =
(fn) -> new FileReader(Paths.get(fn).toFile());
// Alternative, this will compile.
Function<String, CheckedValue<FileReader>> sToFr = (fn) -> {
return CheckedValue.from (
() -> new FileReader(Paths.get("/home/" + f).toFile()));
};
// Single record usage
// The call to get() will propagate the checked exception if it exists.
FileReader readMe = pToFr.apply("/home/README").get();
// List of records usage
List<String> paths = ...; //a list of paths to files
Collection<CheckedValue<FileReader>> frs =
paths.stream().map(pToFr).collect(Collectors.toList());
// Find out if creation of a file reader failed.
boolean anyErrors = frs.stream()
.filter(f -> f.getException().isPresent())
.findAny().isPresent();
What's going on?
A single functional interface that throws a checked exception is created (CheckedValueSupplier). This will be the only functional interface which allows checked exceptions. All other functional interfaces will leverage the CheckedValueSupplier to wrap any code that throws a checked exception.
The CheckedValue class will hold the result of executing any logic that throws a checked exception. This prevents propagation of a checked exception until the point at which code attempts to access the value that an instance of CheckedValue contains.
The problems with this approach.
We are now throwing "Exception" effectively hiding the specific type originally thrown.
We are unaware that an exception occurred until CheckedValue#get() is called.
Consumer et al
Some functional interfaces (Consumer for example) must be handled in a different manner as they don't provide a return value.
Function in lieu of Consumer
One approach is to use a function instead of a consumer, which applies when handling streams.
List<String> lst = Lists.newArrayList();
// won't compile
lst.stream().forEach(e -> throwyMethod(e));
// compiles
lst.stream()
.map(e -> CheckedValueSupplier.from(
() -> {throwyMethod(e); return e;}))
.filter(v -> v.getException().isPresent()); //this example may not actually run due to lazy stream behavior
Escalate
Alternatively, you can always escalate to a RuntimeException. There are other answers that cover escalation of a checked exception from within a Consumer.
Don't consume.
Just avoid functional interfaces all together and use a good-ole-fashioned for loop.
Another solution using a Function wrapper would be to return either an instance of a wrapper of your result, say Success, if everything went well, either an instance of, say Failure.
Some code to clarify things :
public interface ThrowableFunction<A, B> {
B apply(A a) throws Exception;
}
public abstract class Try<A> {
public static boolean isSuccess(Try tryy) {
return tryy instanceof Success;
}
public static <A, B> Function<A, Try<B>> tryOf(ThrowableFunction<A, B> function) {
return a -> {
try {
B result = function.apply(a);
return new Success<B>(result);
} catch (Exception e) {
return new Failure<>(e);
}
};
}
public abstract boolean isSuccess();
public boolean isError() {
return !isSuccess();
}
public abstract A getResult();
public abstract Exception getError();
}
public class Success<A> extends Try<A> {
private final A result;
public Success(A result) {
this.result = result;
}
#Override
public boolean isSuccess() {
return true;
}
#Override
public A getResult() {
return result;
}
#Override
public Exception getError() {
return new UnsupportedOperationException();
}
#Override
public boolean equals(Object that) {
if(!(that instanceof Success)) {
return false;
}
return Objects.equal(result, ((Success) that).getResult());
}
}
public class Failure<A> extends Try<A> {
private final Exception exception;
public Failure(Exception exception) {
this.exception = exception;
}
#Override
public boolean isSuccess() {
return false;
}
#Override
public A getResult() {
throw new UnsupportedOperationException();
}
#Override
public Exception getError() {
return exception;
}
}
A simple use case :
List<Try<Integer>> result = Lists.newArrayList(1, 2, 3).stream().
map(Try.<Integer, Integer>tryOf(i -> someMethodThrowingAnException(i))).
collect(Collectors.toList());
This problem has been bothering me as well; this is why I have created this project.
With it you can do:
final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;
There are a totla of 39 interfaces defined by the JDK which have such a Throwing equivalent; those are all #FunctionalInterfaces used in streams (the base Stream but also IntStream, LongStream and DoubleStream).
And as each of them extend their non throwing counterpart, you can directly use them in lambdas as well:
myStringStream.map(f) // <-- works
The default behavior is that when your throwing lambda throws a checked exception, a ThrownByLambdaException is thrown with the checked exception as the cause. You can therefore capture that and get the cause.
Other features are available as well.
There are a lot of great responses already posted here. Just attempting to solve the problem with a different perspective. Its just my 2 cents, please correct me if I am wrong somewhere.
Throws clause in FunctionalInterface is not a good idea
I think this is probably not a good idea to enforce throws IOException because of following reasons
This looks to me like an anti-pattern to Stream/Lambda. The whole idea is that the caller will decide what code to provide and how to handle the exception. In many scenarios, the IOException might not be applicable for the client. For example, if the client is getting value from cache/memory instead of performing actual I/O.
Also, the exceptions handling in streams becomes really hideous. For example, here is my code will look like if I use your API
acceptMyMethod(s -> {
try {
Integer i = doSomeOperation(s);
return i;
} catch (IOException e) {
// try catch block because of throws clause
// in functional method, even though doSomeOperation
// might not be throwing any exception at all.
e.printStackTrace();
}
return null;
});
Ugly isn't it? Moreover, as I mentioned in my first point, that the doSomeOperation method may or may not be throwing IOException (depending on the implementation of the client/caller), but because of the throws clause in your FunctionalInterface method, I always have to write the try-catch.
What do I do if I really know this API throws IOException
Then probably we are confusing FunctionalInterface with typical Interfaces. If you know this API will throw IOException, then most probably you also know some default/abstract behavior as well. I think you should define an interface and deploy your library (with default/abstract implementation) as follows
public interface MyAmazingAPI {
Integer myMethod(String s) throws IOException;
}
But, the try-catch problem still exists for the client. If I use your API in stream, I still need to handle IOException in hideous try-catch block.
Provide a default stream-friendly API as follows
public interface MyAmazingAPI {
Integer myMethod(String s) throws IOException;
default Optional<Integer> myMethod(String s, Consumer<? super Exception> exceptionConsumer) {
try {
return Optional.ofNullable(this.myMethod(s));
} catch (Exception e) {
if (exceptionConsumer != null) {
exceptionConsumer.accept(e);
} else {
e.printStackTrace();
}
}
return Optional.empty();
}
}
The default method takes the consumer object as argument, which will be responsible to handle the exception. Now, from client's point of view, the code will look like this
strStream.map(str -> amazingAPIs.myMethod(str, Exception::printStackTrace))
.filter(Optional::isPresent)
.map(Optional::get).collect(toList());
Nice right? Of course, logger or other handling logic could be used instead of Exception::printStackTrace.
You can also expose a method similar to https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#exceptionally-java.util.function.Function- . Meaning that you can expose another method, which will contain the exception from previous method call. The disadvantage is that you are now making your APIs stateful, which means that you need to handle thread-safety and which will be eventually become a performance hit. Just an option to consider though.
By default, Java 8 Function does not allow to throw exception and as suggested in multiple answers there are many ways to achieve it, one way is:
#FunctionalInterface
public interface FunctionWithException<T, R, E extends Exception> {
R apply(T t) throws E;
}
Define as:
private FunctionWithException<String, Integer, IOException> myMethod = (str) -> {
if ("abc".equals(str)) {
throw new IOException();
}
return 1;
};
And add throws or try/catch the same exception in caller method.
I use an overloaded utility function called unchecked() which handles multiple use-cases.
SOME EAMPLE USAGES
unchecked(() -> new File("hello.txt").createNewFile());
boolean fileWasCreated = unchecked(() -> new File("hello.txt").createNewFile());
myFiles.forEach(unchecked(file -> new File(file.path).createNewFile()));
SUPPORTING UTILITIES
public class UncheckedUtils {
#FunctionalInterface
public interface ThrowingConsumer<T> {
void accept(T t) throws Exception;
}
#FunctionalInterface
public interface ThrowingSupplier<T> {
T get() throws Exception;
}
#FunctionalInterface
public interface ThrowingRunnable {
void run() throws Exception;
}
public static <T> Consumer<T> unchecked(
ThrowingConsumer<T> throwingConsumer
) {
return i -> {
try {
throwingConsumer.accept(i);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
};
}
public static <T> T unchecked(
ThrowingSupplier<T> throwingSupplier
) {
try {
return throwingSupplier.get();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static void unchecked(
ThrowingRunnable throwing
) {
try {
throwing.run();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
You can use ET for this. ET is a small Java 8 library for exception conversion/translation.
With ET it looks like this:
// Do this once
ExceptionTranslator et = ET.newConfiguration().done();
...
// if your method returns something
Function<String, Integer> f = (t) -> et.withReturningTranslation(() -> myMethod(t));
// if your method returns nothing
Consumer<String> c = (t) -> et.withTranslation(() -> myMethod(t));
ExceptionTranslator instances are thread safe an can be shared by multiple components. You can configure more specific exception conversion rules (e.g. FooCheckedException -> BarRuntimeException) if you like.
If no other rules are available, checked exceptions are automatically converted to RuntimeException.
(Disclaimer: I am the author of ET)
If you don't mind using a third party library, with cyclops-react, a library I contribute to, you can use the FluentFunctions API to write
Function<String, Integer> standardFn = FluentFunctions.ofChecked(this::myMethod);
ofChecked takes a jOOλ CheckedFunction and returns the reference softened back to a standard (unchecked) JDK java.util.function.Function.
Alternatively you can keep working with the captured function via the FluentFunctions api!
For example to execute your method, retrying it up to 5 times and logging it's status you can write
FluentFunctions.ofChecked(this::myMethod)
.log(s->log.debug(s),e->log.error(e,e.getMessage())
.try(5,1000)
.apply("my param");
What I'm doing is to allow the user to give the value he actually want in case of exception .
So I've something looking like this
public static <T, R> Function<? super T, ? extends R> defaultIfThrows(FunctionThatThrows<? super T, ? extends R> delegate, R defaultValue) {
return x -> {
try {
return delegate.apply(x);
} catch (Throwable throwable) {
return defaultValue;
}
};
}
#FunctionalInterface
public interface FunctionThatThrows<T, R> {
R apply(T t) throws Throwable;
}
And this can then be call like :
defaultIfThrows(child -> child.getID(), null)
Use Jool Library or say jOOλ library from JOOQ. It not only provides unchecked exception handled interfaces but also provides Seq class with lots of useful methods.
Also, it contains Functional Interfaces with up to 16 parameters. Also, it provides Tuple class which is used in different scenarios.
Jool Git Link
Specifically in library lookup for org.jooq.lambda.fi.util.function package. It contains all the Interfaces from Java-8 with Checked prepended. See below for reference:-
If you have lombok, you can annotate your method with #SneakyThrows
SneakyThrow does not silently swallow, wrap into RuntimeException, or otherwise modify any exceptions of the listed checked exception types. The JVM does not check for the consistency of the checked exception system; javac does, and this annotation lets you opt out of its mechanism.
https://projectlombok.org/features/SneakyThrows
Several of the offered solutions use a generic argument of E to pass in the type of the exception which gets thrown.
Take that one step further, and rather than passing in the type of the exception, pass in a Consumer of the type of exception, as in...
Consumer<E extends Exception>
You might create several re-usable variations of Consumer<Exception> which would cover the common exception handling needs of your application.
I will do something generic:
public interface Lambda {
#FunctionalInterface
public interface CheckedFunction<T> {
T get() throws Exception;
}
public static <T> T handle(CheckedFunction<T> supplier) {
try {
return supplier.get();
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
}
usage:
Lambda.handle(() -> method());
I'm the author of a tiny lib with some generic magic to throw any Java Exception anywhere without the need of catching them nor wrapping them into RuntimeException.
Usage:
unchecked(() -> methodThrowingCheckedException())
public class UncheckedExceptions {
/**
* throws {#code exception} as unchecked exception, without wrapping exception.
*
* #return will never return anything, return type is set to {#code exception} only to be able to write <code>throw unchecked(exception)</code>
* #throws T {#code exception} as unchecked exception
*/
#SuppressWarnings("unchecked")
public static <T extends Throwable> T unchecked(Exception exception) throws T {
throw (T) exception;
}
#FunctionalInterface
public interface UncheckedFunction<R> {
R call() throws Exception;
}
/**
* Executes given function,
* catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
*
* #return result of function
* #see #unchecked(Exception)
*/
public static <R> R unchecked(UncheckedFunction<R> function) {
try {
return function.call();
} catch (Exception e) {
throw unchecked(e);
}
}
#FunctionalInterface
public interface UncheckedMethod {
void call() throws Exception;
}
/**
* Executes given method,
* catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
*
* #see #unchecked(Exception)
*/
public static void unchecked(UncheckedMethod method) {
try {
method.call();
} catch (Exception e) {
throw unchecked(e);
}
}
}
source: https://github.com/qoomon/unchecked-exceptions-java
For me the preferred solution is to use Lombok. It is a nice library anyway.
Instead of:
Integer myMethod(String s) throws IOException
you will have
import lombok.SneakyThrows;
#SneakyThrows
Integer myMethod(String s)
The exception is still thrown but you do not need to declare it with throws.
public void frankTest() {
int pageId= -1;
List<Book> users= null;
try {
//Does Not Compile: Object page=DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> new Portal(rw.getInt("id"), "", users.parallelStream().filter(uu -> uu.getVbid() == rw.getString("user_id")).findFirst().get(), rw.getString("name")));
//Compiles:
Object page= DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> {
try {
final Book bk= users.stream().filter(bp -> {
String name= null;
try {
name = rw.getString("name");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bp.getTitle().equals(name);
}).limit(1).collect(Collectors.toList()).get(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new Portal(rw.getInt("id"), "", users.get(0), rw.getString("name"));
} );
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I know how to create a reference to a method that has a String parameter and returns an int, it's:
Function<String, Integer>
However, this doesn't work if the function throws an exception, say it's defined as:
Integer myMethod(String s) throws IOException
How would I define this reference?
You'll need to do one of the following.
If it's your code, then define your own functional interface that declares the checked exception:
#FunctionalInterface
public interface CheckedFunction<T, R> {
R apply(T t) throws IOException;
}
and use it:
void foo (CheckedFunction f) { ... }
Otherwise, wrap Integer myMethod(String s) in a method that doesn't declare a checked exception:
public Integer myWrappedMethod(String s) {
try {
return myMethod(s);
}
catch(IOException e) {
throw new UncheckedIOException(e);
}
}
and then:
Function<String, Integer> f = (String t) -> myWrappedMethod(t);
or:
Function<String, Integer> f =
(String t) -> {
try {
return myMethod(t);
}
catch(IOException e) {
throw new UncheckedIOException(e);
}
};
You can actually extend Consumer (and Function etc.) with a new interface that handles exceptions -- using Java 8's default methods!
Consider this interface (extends Consumer):
#FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {
#Override
default void accept(final T elem) {
try {
acceptThrows(elem);
} catch (final Exception e) {
// Implement your own exception handling logic here..
// For example:
System.out.println("handling an exception...");
// Or ...
throw new RuntimeException(e);
}
}
void acceptThrows(T elem) throws Exception;
}
Then, for example, if you have a list:
final List<String> list = Arrays.asList("A", "B", "C");
If you want to consume it (eg. with forEach) with some code that throws exceptions, you would traditionally have set up a try/catch block:
final Consumer<String> consumer = aps -> {
try {
// maybe some other code here...
throw new Exception("asdas");
} catch (final Exception ex) {
System.out.println("handling an exception...");
}
};
list.forEach(consumer);
But with this new interface, you can instantiate it with a lambda expression and the compiler will not complain:
final ThrowingConsumer<String> throwingConsumer = aps -> {
// maybe some other code here...
throw new Exception("asdas");
};
list.forEach(throwingConsumer);
Or even just cast it to be more succinct!:
list.forEach((ThrowingConsumer<String>) aps -> {
// maybe some other code here...
throw new Exception("asda");
});
Update
Looks like there's a very nice utility library part of Durian called Errors which can be used to solve this problem with a lot more flexibility. For example, in my implementation above I've explicitly defined the error handling policy (System.out... or throw RuntimeException), whereas Durian's Errors allow you to apply a policy on the fly via a large suite of utility methods. Thanks for sharing it, #NedTwigg!.
Sample usage:
list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));
I think Durian's Errors class combines many of the pros of the various suggestions above.
Wrap a throwing function to a standard Java 8 functional interface.
Easily specify various policies for handling errors
When wrapping a method that returns a value, there is an important distinction between specifying a default value or rethrowing a RuntimeException.
Throwing versions of Java 8's functional interfaces
Similar to fge's answer
Standard interfaces for throwing specific exceptions
Which addresses Zoltán's concern
To include Durian in your project, you can either:
grab it from jcenter or maven central at com.diffplug.durian:durian:3.3.0
or just copy paste just two small classes into your code: Throwing.java and Errors.java
This is not specific to Java 8. You are trying to compile something equivalent to:
interface I {
void m();
}
class C implements I {
public void m() throws Exception {} //can't compile
}
Disclaimer: I haven't used Java 8 yet, only read about it.
Function<String, Integer> doesn't throw IOException, so you can't put any code in it that throws IOException. If you're calling a method that expects a Function<String, Integer>, then the lambda that you pass to that method can't throw IOException, period. You can either write a lambda like this (I think this is the lambda syntax, not sure):
(String s) -> {
try {
return myMethod(s);
} catch (IOException ex) {
throw new RuntimeException(ex);
// (Or do something else with it...)
}
}
Or, if the method you're passing the lambda to is one you wrote yourself, you can define a new functional interface and use that as the parameter type instead of Function<String, Integer>:
public interface FunctionThatThrowsIOException<I, O> {
O apply(I input) throws IOException;
}
If you don't mind to use a 3rd party lib (Vavr) you could write
CheckedFunction1<String, Integer> f = this::myMethod;
It also has the so-called Try monad which handles errors:
Try(() -> f.apply("test")) // results in a Success(Integer) or Failure(Throwable)
.map(i -> ...) // only executed on Success
...
Please read more here.
Disclaimer: I'm the creator of Vavr.
Sneaky throw idiom enables bypassing CheckedException of Lambda expression. Wrapping a CheckedException in a RuntimeException is not good for strict error handling.
It can be used as a Consumer function used in a Java collection.
Here is a simple and improved version of jib's answer.
import static Throwing.rethrow;
#Test
public void testRethrow() {
thrown.expect(IOException.class);
thrown.expectMessage("i=3");
Arrays.asList(1, 2, 3).forEach(rethrow(e -> {
int i = e.intValue();
if (i == 3) {
throw new IOException("i=" + i);
}
}));
}
This just wrapps the lambda in a rethrow. It makes CheckedException rethrow any Exception that was thrown in your lambda.
public final class Throwing {
private Throwing() {}
#Nonnull
public static <T> Consumer<T> rethrow(#Nonnull final ThrowingConsumer<T> consumer) {
return consumer;
}
/**
* The compiler sees the signature with the throws T inferred to a RuntimeException type, so it
* allows the unchecked exception to propagate.
*
* http://www.baeldung.com/java-sneaky-throws
*/
#SuppressWarnings("unchecked")
#Nonnull
public static <E extends Throwable> void sneakyThrow(#Nonnull Throwable ex) throws E {
throw (E) ex;
}
}
Find a complete code and unit tests here.
You could however create your own FunctionalInterface that throws as below..
#FunctionalInterface
public interface UseInstance<T, X extends Throwable> {
void accept(T instance) throws X;
}
then implement it using Lambdas or references as shown below.
import java.io.FileWriter;
import java.io.IOException;
//lambda expressions and the execute around method (EAM) pattern to
//manage resources
public class FileWriterEAM {
private final FileWriter writer;
private FileWriterEAM(final String fileName) throws IOException {
writer = new FileWriter(fileName);
}
private void close() throws IOException {
System.out.println("close called automatically...");
writer.close();
}
public void writeStuff(final String message) throws IOException {
writer.write(message);
}
//...
public static void use(final String fileName, final UseInstance<FileWriterEAM, IOException> block) throws IOException {
final FileWriterEAM writerEAM = new FileWriterEAM(fileName);
try {
block.accept(writerEAM);
} finally {
writerEAM.close();
}
}
public static void main(final String[] args) throws IOException {
FileWriterEAM.use("eam.txt", writerEAM -> writerEAM.writeStuff("sweet"));
FileWriterEAM.use("eam2.txt", writerEAM -> {
writerEAM.writeStuff("how");
writerEAM.writeStuff("sweet");
});
FileWriterEAM.use("eam3.txt", FileWriterEAM::writeIt);
}
void writeIt() throws IOException{
this.writeStuff("How ");
this.writeStuff("sweet ");
this.writeStuff("it is");
}
}
You can use unthrow wrapper
Function<String, Integer> func1 = s -> Unthrow.wrap(() -> myMethod(s));
or
Function<String, Integer> func2 = s1 -> Unthrow.wrap((s2) -> myMethod(s2), s1);
You can.
Extending #marcg 's UtilException and adding generic <E extends Exception> where necessary: this way, the compiler will force you again to add throw clauses and everything's as if you could throw checked exceptions natively on java 8's streams.
public final class LambdaExceptionUtil {
#FunctionalInterface
public interface Function_WithExceptions<T, R, E extends Exception> {
R apply(T t) throws E;
}
/**
* .map(rethrowFunction(name -> Class.forName(name))) or .map(rethrowFunction(Class::forName))
*/
public static <T, R, E extends Exception> Function<T, R> rethrowFunction(Function_WithExceptions<T, R, E> function) throws E {
return t -> {
try {
return function.apply(t);
} catch (Exception exception) {
throwActualException(exception);
return null;
}
};
}
#SuppressWarnings("unchecked")
private static <E extends Exception> void throwActualException(Exception exception) throws E {
throw (E) exception;
}
}
public class LambdaExceptionUtilTest {
#Test
public void testFunction() throws MyTestException {
List<Integer> sizes = Stream.of("ciao", "hello").<Integer>map(rethrowFunction(s -> transform(s))).collect(toList());
assertEquals(2, sizes.size());
assertEquals(4, sizes.get(0).intValue());
assertEquals(5, sizes.get(1).intValue());
}
private Integer transform(String value) throws MyTestException {
if(value==null) {
throw new MyTestException();
}
return value.length();
}
private static class MyTestException extends Exception { }
}
I had this problem with Class.forName and Class.newInstance inside a lambda, so I just did:
public Object uncheckedNewInstanceForName (String name) {
try {
return Class.forName(name).newInstance();
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
Inside the lambda, instead of calling Class.forName("myClass").newInstance() I just called uncheckedNewInstanceForName ("myClass")
Create a custom return type that will propagate the checked exception. This is an alternative to creating a new interface that mirrors the existing functional interface with the slight modification of a "throws exception" on the functional interface's method.
Definition
CheckedValueSupplier
public static interface CheckedValueSupplier<V> {
public V get () throws Exception;
}
CheckedValue
public class CheckedValue<V> {
private final V v;
private final Optional<Exception> opt;
public Value (V v) {
this.v = v;
}
public Value (Exception e) {
this.opt = Optional.of(e);
}
public V get () throws Exception {
if (opt.isPresent()) {
throw opt.get();
}
return v;
}
public Optional<Exception> getException () {
return opt;
}
public static <T> CheckedValue<T> returns (T t) {
return new CheckedValue<T>(t);
}
public static <T> CheckedValue<T> rethrows (Exception e) {
return new CheckedValue<T>(e);
}
public static <V> CheckedValue<V> from (CheckedValueSupplier<V> sup) {
try {
return CheckedValue.returns(sup.get());
} catch (Exception e) {
return Result.rethrows(e);
}
}
public static <V> CheckedValue<V> escalates (CheckedValueSupplier<V> sup) {
try {
return CheckedValue.returns(sup.get());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Usage
// Don't use this pattern with FileReader, it's meant to be an
// example. FileReader is a Closeable resource and as such should
// be managed in a try-with-resources block or in another safe
// manner that will make sure it is closed properly.
// This will not compile as the FileReader constructor throws
// an IOException.
Function<String, FileReader> sToFr =
(fn) -> new FileReader(Paths.get(fn).toFile());
// Alternative, this will compile.
Function<String, CheckedValue<FileReader>> sToFr = (fn) -> {
return CheckedValue.from (
() -> new FileReader(Paths.get("/home/" + f).toFile()));
};
// Single record usage
// The call to get() will propagate the checked exception if it exists.
FileReader readMe = pToFr.apply("/home/README").get();
// List of records usage
List<String> paths = ...; //a list of paths to files
Collection<CheckedValue<FileReader>> frs =
paths.stream().map(pToFr).collect(Collectors.toList());
// Find out if creation of a file reader failed.
boolean anyErrors = frs.stream()
.filter(f -> f.getException().isPresent())
.findAny().isPresent();
What's going on?
A single functional interface that throws a checked exception is created (CheckedValueSupplier). This will be the only functional interface which allows checked exceptions. All other functional interfaces will leverage the CheckedValueSupplier to wrap any code that throws a checked exception.
The CheckedValue class will hold the result of executing any logic that throws a checked exception. This prevents propagation of a checked exception until the point at which code attempts to access the value that an instance of CheckedValue contains.
The problems with this approach.
We are now throwing "Exception" effectively hiding the specific type originally thrown.
We are unaware that an exception occurred until CheckedValue#get() is called.
Consumer et al
Some functional interfaces (Consumer for example) must be handled in a different manner as they don't provide a return value.
Function in lieu of Consumer
One approach is to use a function instead of a consumer, which applies when handling streams.
List<String> lst = Lists.newArrayList();
// won't compile
lst.stream().forEach(e -> throwyMethod(e));
// compiles
lst.stream()
.map(e -> CheckedValueSupplier.from(
() -> {throwyMethod(e); return e;}))
.filter(v -> v.getException().isPresent()); //this example may not actually run due to lazy stream behavior
Escalate
Alternatively, you can always escalate to a RuntimeException. There are other answers that cover escalation of a checked exception from within a Consumer.
Don't consume.
Just avoid functional interfaces all together and use a good-ole-fashioned for loop.
Another solution using a Function wrapper would be to return either an instance of a wrapper of your result, say Success, if everything went well, either an instance of, say Failure.
Some code to clarify things :
public interface ThrowableFunction<A, B> {
B apply(A a) throws Exception;
}
public abstract class Try<A> {
public static boolean isSuccess(Try tryy) {
return tryy instanceof Success;
}
public static <A, B> Function<A, Try<B>> tryOf(ThrowableFunction<A, B> function) {
return a -> {
try {
B result = function.apply(a);
return new Success<B>(result);
} catch (Exception e) {
return new Failure<>(e);
}
};
}
public abstract boolean isSuccess();
public boolean isError() {
return !isSuccess();
}
public abstract A getResult();
public abstract Exception getError();
}
public class Success<A> extends Try<A> {
private final A result;
public Success(A result) {
this.result = result;
}
#Override
public boolean isSuccess() {
return true;
}
#Override
public A getResult() {
return result;
}
#Override
public Exception getError() {
return new UnsupportedOperationException();
}
#Override
public boolean equals(Object that) {
if(!(that instanceof Success)) {
return false;
}
return Objects.equal(result, ((Success) that).getResult());
}
}
public class Failure<A> extends Try<A> {
private final Exception exception;
public Failure(Exception exception) {
this.exception = exception;
}
#Override
public boolean isSuccess() {
return false;
}
#Override
public A getResult() {
throw new UnsupportedOperationException();
}
#Override
public Exception getError() {
return exception;
}
}
A simple use case :
List<Try<Integer>> result = Lists.newArrayList(1, 2, 3).stream().
map(Try.<Integer, Integer>tryOf(i -> someMethodThrowingAnException(i))).
collect(Collectors.toList());
This problem has been bothering me as well; this is why I have created this project.
With it you can do:
final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;
There are a totla of 39 interfaces defined by the JDK which have such a Throwing equivalent; those are all #FunctionalInterfaces used in streams (the base Stream but also IntStream, LongStream and DoubleStream).
And as each of them extend their non throwing counterpart, you can directly use them in lambdas as well:
myStringStream.map(f) // <-- works
The default behavior is that when your throwing lambda throws a checked exception, a ThrownByLambdaException is thrown with the checked exception as the cause. You can therefore capture that and get the cause.
Other features are available as well.
There are a lot of great responses already posted here. Just attempting to solve the problem with a different perspective. Its just my 2 cents, please correct me if I am wrong somewhere.
Throws clause in FunctionalInterface is not a good idea
I think this is probably not a good idea to enforce throws IOException because of following reasons
This looks to me like an anti-pattern to Stream/Lambda. The whole idea is that the caller will decide what code to provide and how to handle the exception. In many scenarios, the IOException might not be applicable for the client. For example, if the client is getting value from cache/memory instead of performing actual I/O.
Also, the exceptions handling in streams becomes really hideous. For example, here is my code will look like if I use your API
acceptMyMethod(s -> {
try {
Integer i = doSomeOperation(s);
return i;
} catch (IOException e) {
// try catch block because of throws clause
// in functional method, even though doSomeOperation
// might not be throwing any exception at all.
e.printStackTrace();
}
return null;
});
Ugly isn't it? Moreover, as I mentioned in my first point, that the doSomeOperation method may or may not be throwing IOException (depending on the implementation of the client/caller), but because of the throws clause in your FunctionalInterface method, I always have to write the try-catch.
What do I do if I really know this API throws IOException
Then probably we are confusing FunctionalInterface with typical Interfaces. If you know this API will throw IOException, then most probably you also know some default/abstract behavior as well. I think you should define an interface and deploy your library (with default/abstract implementation) as follows
public interface MyAmazingAPI {
Integer myMethod(String s) throws IOException;
}
But, the try-catch problem still exists for the client. If I use your API in stream, I still need to handle IOException in hideous try-catch block.
Provide a default stream-friendly API as follows
public interface MyAmazingAPI {
Integer myMethod(String s) throws IOException;
default Optional<Integer> myMethod(String s, Consumer<? super Exception> exceptionConsumer) {
try {
return Optional.ofNullable(this.myMethod(s));
} catch (Exception e) {
if (exceptionConsumer != null) {
exceptionConsumer.accept(e);
} else {
e.printStackTrace();
}
}
return Optional.empty();
}
}
The default method takes the consumer object as argument, which will be responsible to handle the exception. Now, from client's point of view, the code will look like this
strStream.map(str -> amazingAPIs.myMethod(str, Exception::printStackTrace))
.filter(Optional::isPresent)
.map(Optional::get).collect(toList());
Nice right? Of course, logger or other handling logic could be used instead of Exception::printStackTrace.
You can also expose a method similar to https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#exceptionally-java.util.function.Function- . Meaning that you can expose another method, which will contain the exception from previous method call. The disadvantage is that you are now making your APIs stateful, which means that you need to handle thread-safety and which will be eventually become a performance hit. Just an option to consider though.
By default, Java 8 Function does not allow to throw exception and as suggested in multiple answers there are many ways to achieve it, one way is:
#FunctionalInterface
public interface FunctionWithException<T, R, E extends Exception> {
R apply(T t) throws E;
}
Define as:
private FunctionWithException<String, Integer, IOException> myMethod = (str) -> {
if ("abc".equals(str)) {
throw new IOException();
}
return 1;
};
And add throws or try/catch the same exception in caller method.
I use an overloaded utility function called unchecked() which handles multiple use-cases.
SOME EAMPLE USAGES
unchecked(() -> new File("hello.txt").createNewFile());
boolean fileWasCreated = unchecked(() -> new File("hello.txt").createNewFile());
myFiles.forEach(unchecked(file -> new File(file.path).createNewFile()));
SUPPORTING UTILITIES
public class UncheckedUtils {
#FunctionalInterface
public interface ThrowingConsumer<T> {
void accept(T t) throws Exception;
}
#FunctionalInterface
public interface ThrowingSupplier<T> {
T get() throws Exception;
}
#FunctionalInterface
public interface ThrowingRunnable {
void run() throws Exception;
}
public static <T> Consumer<T> unchecked(
ThrowingConsumer<T> throwingConsumer
) {
return i -> {
try {
throwingConsumer.accept(i);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
};
}
public static <T> T unchecked(
ThrowingSupplier<T> throwingSupplier
) {
try {
return throwingSupplier.get();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static void unchecked(
ThrowingRunnable throwing
) {
try {
throwing.run();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
You can use ET for this. ET is a small Java 8 library for exception conversion/translation.
With ET it looks like this:
// Do this once
ExceptionTranslator et = ET.newConfiguration().done();
...
// if your method returns something
Function<String, Integer> f = (t) -> et.withReturningTranslation(() -> myMethod(t));
// if your method returns nothing
Consumer<String> c = (t) -> et.withTranslation(() -> myMethod(t));
ExceptionTranslator instances are thread safe an can be shared by multiple components. You can configure more specific exception conversion rules (e.g. FooCheckedException -> BarRuntimeException) if you like.
If no other rules are available, checked exceptions are automatically converted to RuntimeException.
(Disclaimer: I am the author of ET)
If you don't mind using a third party library, with cyclops-react, a library I contribute to, you can use the FluentFunctions API to write
Function<String, Integer> standardFn = FluentFunctions.ofChecked(this::myMethod);
ofChecked takes a jOOλ CheckedFunction and returns the reference softened back to a standard (unchecked) JDK java.util.function.Function.
Alternatively you can keep working with the captured function via the FluentFunctions api!
For example to execute your method, retrying it up to 5 times and logging it's status you can write
FluentFunctions.ofChecked(this::myMethod)
.log(s->log.debug(s),e->log.error(e,e.getMessage())
.try(5,1000)
.apply("my param");
What I'm doing is to allow the user to give the value he actually want in case of exception .
So I've something looking like this
public static <T, R> Function<? super T, ? extends R> defaultIfThrows(FunctionThatThrows<? super T, ? extends R> delegate, R defaultValue) {
return x -> {
try {
return delegate.apply(x);
} catch (Throwable throwable) {
return defaultValue;
}
};
}
#FunctionalInterface
public interface FunctionThatThrows<T, R> {
R apply(T t) throws Throwable;
}
And this can then be call like :
defaultIfThrows(child -> child.getID(), null)
Use Jool Library or say jOOλ library from JOOQ. It not only provides unchecked exception handled interfaces but also provides Seq class with lots of useful methods.
Also, it contains Functional Interfaces with up to 16 parameters. Also, it provides Tuple class which is used in different scenarios.
Jool Git Link
Specifically in library lookup for org.jooq.lambda.fi.util.function package. It contains all the Interfaces from Java-8 with Checked prepended. See below for reference:-
If you have lombok, you can annotate your method with #SneakyThrows
SneakyThrow does not silently swallow, wrap into RuntimeException, or otherwise modify any exceptions of the listed checked exception types. The JVM does not check for the consistency of the checked exception system; javac does, and this annotation lets you opt out of its mechanism.
https://projectlombok.org/features/SneakyThrows
Several of the offered solutions use a generic argument of E to pass in the type of the exception which gets thrown.
Take that one step further, and rather than passing in the type of the exception, pass in a Consumer of the type of exception, as in...
Consumer<E extends Exception>
You might create several re-usable variations of Consumer<Exception> which would cover the common exception handling needs of your application.
I will do something generic:
public interface Lambda {
#FunctionalInterface
public interface CheckedFunction<T> {
T get() throws Exception;
}
public static <T> T handle(CheckedFunction<T> supplier) {
try {
return supplier.get();
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
}
usage:
Lambda.handle(() -> method());
I'm the author of a tiny lib with some generic magic to throw any Java Exception anywhere without the need of catching them nor wrapping them into RuntimeException.
Usage:
unchecked(() -> methodThrowingCheckedException())
public class UncheckedExceptions {
/**
* throws {#code exception} as unchecked exception, without wrapping exception.
*
* #return will never return anything, return type is set to {#code exception} only to be able to write <code>throw unchecked(exception)</code>
* #throws T {#code exception} as unchecked exception
*/
#SuppressWarnings("unchecked")
public static <T extends Throwable> T unchecked(Exception exception) throws T {
throw (T) exception;
}
#FunctionalInterface
public interface UncheckedFunction<R> {
R call() throws Exception;
}
/**
* Executes given function,
* catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
*
* #return result of function
* #see #unchecked(Exception)
*/
public static <R> R unchecked(UncheckedFunction<R> function) {
try {
return function.call();
} catch (Exception e) {
throw unchecked(e);
}
}
#FunctionalInterface
public interface UncheckedMethod {
void call() throws Exception;
}
/**
* Executes given method,
* catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
*
* #see #unchecked(Exception)
*/
public static void unchecked(UncheckedMethod method) {
try {
method.call();
} catch (Exception e) {
throw unchecked(e);
}
}
}
source: https://github.com/qoomon/unchecked-exceptions-java
For me the preferred solution is to use Lombok. It is a nice library anyway.
Instead of:
Integer myMethod(String s) throws IOException
you will have
import lombok.SneakyThrows;
#SneakyThrows
Integer myMethod(String s)
The exception is still thrown but you do not need to declare it with throws.
public void frankTest() {
int pageId= -1;
List<Book> users= null;
try {
//Does Not Compile: Object page=DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> new Portal(rw.getInt("id"), "", users.parallelStream().filter(uu -> uu.getVbid() == rw.getString("user_id")).findFirst().get(), rw.getString("name")));
//Compiles:
Object page= DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> {
try {
final Book bk= users.stream().filter(bp -> {
String name= null;
try {
name = rw.getString("name");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bp.getTitle().equals(name);
}).limit(1).collect(Collectors.toList()).get(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new Portal(rw.getInt("id"), "", users.get(0), rw.getString("name"));
} );
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I am working on some workflow and it is possible to raise many exceptions in that. I heard that we can keep all those possible exceptions in an Enum (Exception1, Exception2 ...) and use it. How can we do that using Enums in Java?
You can add the classes of exceptions with
enum EnumWithExceptions {
ENUM1(Exception1.class, Exception2.class),
ENUM2(Exception3.class);
private final Class<? extends Exception>[] exceptions;
private EnumWithExceptions(Class<? extends Exception>... exceptions) {
this.exceptions = exceptions;
}
public boolean matches(Exception e) {
for(Class<? extends Exception> e2: exceptions)
if (e2.isInstance(e)) return true;
return false;
}
}
} catch(Exception e){
if (ENUM1.matches(e)){
//do something
} else if(ENUM2.matches(e)) {
//do something
} else {
//do something
}
}
enum Fred {
SAM(AnException.class),
I(AnotherException.class),
AM(YetAnotherException.class)
;
private Throwable t;
Fred(Throwable throwable) {
this.t = throwable;
}
public Throwable getThrowable() {
return t;
}
}
...
throw Fred.SAM.getThrowable();
Why not store the exceptions in an ArrayList? Or if you want to name the index, you could use a HashMap.
import java.util.ArrayList;
import java.util.HashMap;
public final class ExceptionStorage {
private static int exceptionCount = 0;
private static HashMap<String, Exception> indexedExceptions = new HashMap<>();
private static ArrayList<Exception> exceptions = new ArrayList();
public static void addException(Exception e) {
exceptions.add(e);
}
public static void putException(Exception e) {
indexedExceptions.put("Exception" + (++exceptionCount), e);
}
public static ArrayList<Exception> getUnindexedExceptions() {
return this.exceptions;
}
public static HashMap<String, Exception> getIndexedExceptions() {
return this.indexedExceptions;
}
}
Obviously you would have to modify the code to use either ArrayList or HashMap, but I think this would be a better solution than using Enums.