Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compilation fails for JDK 11 and compiles fine for JDK 8

The code compiles fine with JDK 8 (1.8.0_212) but fails to compile using JDK 11 (11.0.3) both Oracle jdk and open jdk (aws corretto)

Tried compiling using javac and with Maven (maven version 3.6.1 and maven-compiler-plugin version 3.8.0) it compiles for JDK 8 and fails for JDK 11.

import java.net.URL;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.Stream;

public class AppDemo {
    public static void main(String[] args) {
        // NO error here
        giveMeStream("http://foo.com").map(wrap(url -> new URL(url)));

        List<String> list = new ArrayList<String>();
        list.add("http://foo.com/, http://bar.com/");
        // error: unreported exception MalformedURLException;
        // must be caught or declared to be thrown
        list.stream().flatMap(
            urls -> Arrays.<String>stream(urls.split(",")).map(wrap(url -> new URL(url)))
        );

        // error: unreported exception MalformedURLException;
        // must be caught or declared to be thrown
        Stream.concat(
            giveMeStream("http://foo.com").map(wrap(url -> new URL(url))),
            giveMeStream("http://bar.com").map(wrap(url -> new URL(url))));

    }


    static Stream<String> giveMeStream(String s) {
        return Arrays.stream(new String[]{s});
    }

    static <T, R, E extends Throwable> Function<T, R>
    wrap(FunException<T, R, E> fn) {
        return t -> {
            try {
                return fn.apply(t);
            } catch (Throwable throwable) {
                throw new RuntimeException(throwable);
            }
        };
    }

    interface FunException<T, R, E extends Throwable> {
        R apply(T t) throws E;
    }
}

Error:

Expected : No compilation error
Actual : compilation error for JDK11
Error message with JDK 11:

s.<String>stream(urls.split(",")).map(wrap(url -> new URL(url)))
                                                               ^
AppDemo.java:24: error: unreported exception MalformedURLException; must be caught or declared to be thrown
            giveMeStream("http://foo.com").map(wrap(url -> new URL(url))),
                                                           ^
AppDemo.java:25: error: unreported exception MalformedURLException; must be caught or declared to be thrown
            giveMeStream("http://bar.com").map(wrap(url -> new URL(url))));
                                                           ^
3 errors
like image 409
Fazal Avatar asked Jun 26 '19 10:06

Fazal


1 Answers

Because slight updates to the spec say so, probably. Does it matter? It's not going to work like this.

There is no real purpose to turning the exception thrown into a parameterized type here. Also, youll make quite the chain of RuntimeException with this code. Try this, instead:

static <T, R> Function<T, R> wrap(FunException<T, R> fn) {
    return t -> {
        try {
            return fn.apply(t);
        } catch (Error | RuntimeException ex) {
            throw ex;
        } catch (Throwable throwable) {
            throw new RuntimeException("Checked exception in lambda", throwable);
        }
    };
}

interface FunException<T, R> {
    R apply(T t) throws Throwable;
}

and now it'll compile fine.

TO THE READER: Don't do this. The correct way to deal with java's rules such as checked exceptions is to deal with them. Using hacks to get around the essence of a language just means your code is non-idiomatic (others who read your code won't get it, and you'll have a hard time reading the code of others. That's bad), tends to interop with other libraries in a bad way, and various features that are supposed to help, now hurt (example: Here you get a LOT of causal exception chains which make the reading of your logs and exception traces more difficult than is needed). Also, being 'off the beaten path' this far leads to fun times such as code that used to compile no longer compiling.

like image 161
rzwitserloot Avatar answered Sep 30 '22 15:09

rzwitserloot