Hi Sameera, I came across a the topic of exception handling in functional interfaces when going through the book 'Java 8 for the Really Impatient - Cay S. Horstmann' which was recommended by my mentor Azeez. The book however says that what is suggested is a solution but not a complete fix.
The suggested solution is to use functional interfaces whose methods allow checked exceptions. For example, the *T get( ) *method of functional interface *Supplier<T>* do not allow checked exceptions. But, the functional interface *Callable<T>* has a method that is declared as *T call( ) throws exception*, which allows checked exceptions. Therefore, the fix would be to use *Callable<T>* instead of *Supplier<T>*. I tried this fix for an example. [1] In the example given, stream.map( ) method maps objects to another value as specified by a Function<T,R> object. Since a functional interface that allows checked exceptions corresponding to* Function<T,R>* is not available, I created a functional interface called *CheckedFunction<T,R>* which has a single abstract method that throws a *ClassNotFoundException*. I have replaced the *Function<T,R>* interface using *CheckedFunction<T,R>* by writing the *unchecked* method. import java.util.function.Function; import java.util.stream.Stream; public class Example { public static void main(String[] args) { Stream.of("java.lang.String", "java.lang.Integer") .map(unchecked(Class::forName)) .forEach(System.out::println); } public static <T, R> Function<T, R> unchecked(CheckedFunction<? super T, ? extends R> function) { return arg -> { try { return function.apply(arg); } catch (Exception e) { throw new RuntimeException(e); } }; } } interface CheckedFunction<T, R> { R apply(T t) throws ClassNotFoundException; } According to the book, we can implement a version of the *unchecked *method to deal with lambdas that throws checked exceptions, given that we can find or provide a functional interface whose abstract method throws arbitrary exceptions. [1] https://lochanaranaweera.wordpress.com/2015/11/27/417/ Thanks and regards, On Wed, Mar 2, 2016 at 11:41 AM, Sameera Jayasoma <same...@wso2.com> wrote: > You cannot throw checked exceptions from inside Lambda expression/Streams > in Java 8. This is a well-known issue and there are tons of discussions > about this. Oracle has not provided a solution yet. Some people say that > Oracle messed it up. Anyway developers around the globe have come up with > several workarounds. With C5 effort, we are starting to use Java 8 heavily. > Therefore we need to agree on a workaround soon. > > You probably need to have some experience with Java 8 Lambdas and Streams > in order to understand this issue. Lets me explain some of the Java 8 > concepts briefly. I am using few sample code snippets extracted from > various sources. > > *Introduction to Java8* > > *Streams* - Represents a sequence of elements. Streams supports > sequential and parallel aggregate operations. In the following example, If > an element starts with "c", then the element is converted to uppercase. All > such converted elements are sorted and output to the System.out. JVM > invokes these operations in an optimized manner, not necessarily in the > order we've specified. > > List<String> list = Arrays.asList("a1", "a2", "b1", "c2", "c1"); > > list > .stream() > .filter(s -> s.startsWith("c")) > .map(String::toUpperCase) > .sorted() > .forEach(System.out::println); > > // C1 > // C2 > > > *Lambda Expression* - Represents a function which can be created and > passed around without belonging to any class. This function can be executed > on demand as well. Take a look at the following example. > > list > .stream() > .filter(s -> s.startsWith("c")) > > Expression inside the filter method is called a lambda expression which > takes a String object as an argument and returns a boolean. Lambda > expressions are equivalent to interfaces with one abstract method. This is > how lambda expressions are modeled in Java8. These interfaces are called > Functional Interfaces in Java 8. Following is a sample functional > interface. Above lambda expression is mapped to the following functional > interface that comes with Java by default. A point to note is that, None of > these standard functional interfaces available in Java 8 allow to forward > checked exceptions to the caller. > > @FunctionalInterfacepublic interface Predicate<T> { > boolean test(T t);} > > Now that you have a brief understanding of some of the Java 8 features, > let's look at the problem related to checked exceptions. > > > *Checked Exceptions and Stream, Lambdas, Functional Interfaces* > > The test method of the Predicate interface has not declared any exceptions > in the method signature. What if a checked exception is thrown inside an > implementation of the test method, how can we forward this exception to the > caller of the test method. There is no straight-forward way to solve this > issue. One workaround would be to throw a RuntimeException which wraps the > checked exception. It is not a very elegant solution though. > > Let me take an example to illustrate this issue more clearly. > > public List<Class> getClasses() throws* ClassNotFoundException* { > Stream.of("java.lang.String", "java.lang.Integer") > .map(className -> Class.forName(className)) > .foreach(clazz -> System.out.println(clazz.getName());} > > Above code snippet doesn't compile. Why? Class.forName() method throws a > checked exception called ClassNotException, but its not possible to throw > this exception from the lambda expression. You could deal with this problem > in the following manner. But it is not a proper solution. > > public List<Class> getClasses() throws* ClassNotFoundException* { > Stream.of("java.lang.String", "java.lang.Integer") > .map(className -> { > try { > return Class.forName(className); > } catch(ClassNotFoundException e) { > e.printStackTrace(); throw new > RuntimeException(e); > } }) .foreach(clazz -> > System.out.println(clazz.getName());} > > We need to find a better workaround to this issue. I found one such > workaround by googling. I will test it and update this thread ASAP. In the > meantime, if you can think of a proper workaround, please update this > thread. If required we can have a meeting to discuss this further. > > Thanks, > Sameera. > > [1] > http://stackoverflow.com/questions/27644361/how-can-i-throw-checked-exceptions-from-inside-java-8-streams > [2] https://dzone.com/articles/java-8-functional-interfaces-0 > [3] > http://programmers.stackexchange.com/questions/225931/workaround-for-java-checked-exceptions > > -- > Sameera Jayasoma, > Software Architect, > > WSO2, Inc. (http://wso2.com) > email: same...@wso2.com > blog: http://blog.sameera.org > twitter: https://twitter.com/sameerajayasoma > flickr: http://www.flickr.com/photos/sameera-jayasoma/collections > Mobile: 0094776364456 > > Lean . Enterprise . Middleware > > > > _______________________________________________ > Architecture mailing list > Architecture@wso2.org > https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture > > -- Lochana Ranaweera Intern Software Engineer WSO2 Inc: http://wso2.com Blog: https://lochanaranaweera.wordpress.com/ Mobile: +94716487055 <http://tel%2B716487055>
_______________________________________________ Architecture mailing list Architecture@wso2.org https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture