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

Reply via email to