In fully functional languages, there is a concept called "Try Monad". This is the perfect solution, but typing that in Java is a bit cumbersome. But there are some attempts like [1]. Google "Try Monad", to find more options.
[1] https://github.com/aol/cyclops/wiki/Try-:-functional-exception-handling-for-Java-8 On Sun, Feb 28, 2016 at 2:44 AM, Sameera Jayasoma <[email protected]> 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: [email protected] > blog: http://blog.sameera.org > twitter: https://twitter.com/sameerajayasoma > flickr: http://www.flickr.com/photos/sameera-jayasoma/collections > Mobile: 0094776364456 > > Lean . Enterprise . Middleware > > -- With regards, *Manu*ranga Perera. phone : 071 7 70 20 50 mail : [email protected]
_______________________________________________ Architecture mailing list [email protected] https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
