71

I'm playing with the new lambda features in Java 8, and found that the practices offered by Java 8 are really useful. However, I'm wondering is there a good way to make a work-around for the following scenario. Suppose you have an object pool wrapper that requires some kind of a factory to fill the object pool, for example (using java.lang.functions.Factory):

public class JdbcConnectionPool extends ObjectPool<Connection> {

    public ConnectionPool(int maxConnections, String url) {
        super(new Factory<Connection>() {
            @Override
            public Connection make() {
                try {
                    return DriverManager.getConnection(url);
                } catch ( SQLException ex ) {
                    throw new RuntimeException(ex);
                }
            }
        }, maxConnections);
    }

}

After transforming the functional interface into lambda expression, the code above becomes like that:

public class JdbcConnectionPool extends ObjectPool<Connection> {

    public ConnectionPool(int maxConnections, String url) {
        super(() -> {
            try {
                return DriverManager.getConnection(url);
            } catch ( SQLException ex ) {
                throw new RuntimeException(ex);
            }
        }, maxConnections);
    }

}

Not so bad indeed, but the checked exception java.sql.SQLException requires a try/catch block inside the lambda. At my company we use two interfaces for long time:

  • IOut<T> that is an equivalent to java.lang.functions.Factory;
  • and a special interface for the cases that usually require checked exceptions propagation: interface IUnsafeOut<T, E extends Throwable> { T out() throws E; }.

Both IOut<T> and IUnsafeOut<T> are supposed to be removed during migration to Java 8, however there is no exact match for IUnsafeOut<T, E>. If the lambda expressions could deal with checked exceptions like they were unchecked, it could be possible to use simply like the following in the constructor above:

super(() -> DriverManager.getConnection(url), maxConnections);

That looks much cleaner. I see that I can rewrite the ObjectPool super class to accept our IUnsafeOut<T>, but as far as I know, Java 8 is not finished yet, so could be there some changes like:

  • implementing something similar to IUnsafeOut<T, E>? (to be honest, I consider that dirty - the subject must choose what to accept: either Factory or "unsafe factory" that cannot have compatible method signatures)
  • simply ignoring checked exceptions in lambdas, so no need in IUnsafeOut<T, E> surrogates? (why not? e.g. another important change: OpenJDK, that I use, javac now does not require variables and parameters to be declared as final to be captured in an anonymous class [functional interface] or lambda expression)

So the question is generally is: is there a way to bypass checked exceptions in lambdas or is it planned in the future until Java 8 is finally released?


Update 1

Hm-m-m, as far as I understand what we currently have, it seems there is no way at the moment, despite the referenced article is dated from 2010: Brian Goetz explains exception transparency in Java. If nothing changed much in Java 8, this could be considered an answer. Also Brian says that interface ExceptionalCallable<V, E extends Exception> (what I mentioned as IUnsafeOut<T, E extends Throwable> out of our code legacy) is pretty much useless, and I agree with him.

Do I still miss something else?

Sled
  • 18,541
  • 27
  • 119
  • 168
Lyubomyr Shaydariv
  • 20,327
  • 12
  • 64
  • 105
  • 3
    For anyone following the evolution of the lambdas API, it's worth noting that java.util.functions.Factory::make is now java.util.function.Supplier::get. You can see an up-to-date version of the API docs at http://lambdadoc.net, a subsite of the [Lambda FAQ] (http://lambdafaq.org) – Maurice Naftalin Dec 26 '12 at 14:50
  • @MauriceNaftalin, thanks for the comment. I currently use OpenJDK 1.8.0-EA. – Lyubomyr Shaydariv Dec 26 '12 at 14:59
  • 1
    one approach is given in [this blog](http://java8blog.com/post/37385501926/fixing-checked-exceptions-in-java-8) – Matt Dec 26 '12 at 18:22
  • 3
    The exception transparency writeup to which you refer was simply a candidate proposal, which was later deemed to be flawed after examination in greater detail. – Brian Goetz Jan 12 '15 at 22:27
  • @Matt the link is broken – kopelitsa May 09 '16 at 10:16

9 Answers9

49

Not sure I really answer your question, but couldn't you simply use something like that?

public final class SupplierUtils {
    private SupplierUtils() {
    }

    public static <T> Supplier<T> wrap(Callable<T> callable) {
        return () -> {
            try {
                return callable.call();
            }
            catch (RuntimeException e) {
                throw e;
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        };
    }
}

public class JdbcConnectionPool extends ObjectPool<Connection> {

    public JdbcConnectionPool(int maxConnections, String url) {
        super(SupplierUtils.wrap(() -> DriverManager.getConnection(url)), maxConnections);
    }
}
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 3
    Thanks! Yes, your approach seems to be a possible solution in the terms of current Java 8 features (this also was suggested by Matt in a post comment via Guava Throwables http://java8blog.com/post/37385501926/fixing-checked-exceptions-in-java-8 ). It also seems to be the most elegant solution, but, I guess you also agree, that's a little boiler-plate. Brian Goetz in 2010 tried something to solve this problem using something like _variadic type parameters_, and probably Java will get this fixed somehow, who knows. – Lyubomyr Shaydariv Dec 26 '12 at 20:27
  • 11
    Yet another great example of checked exception abuse. Wrapping the exception in RuntimeException might be necessary in this case, but failing to unwrap it again on the outside defeats the entire point of checked exceptions. Please take the time to read why checked exceptions exist and when they should be used: http://stackoverflow.com/a/19061110/14731 – Gili Feb 15 '14 at 21:05
  • 17
    @Gili Checked exceptions are an abuse of programmer, not vice versa. They promote boilerplate code, incidental complexity, and downright programming errors. They break program flow, especially because `try-catch` is a statement and not an expression. Wrapping exceptions is a) a nuisance, b) little more than a hack and work around the basic misdesign. – Marko Topolnik Mar 21 '14 at 10:18
  • 7
    99% of real-life program logic requires checked and unchecked exceptions alike to break the current unit of work and have them uniformly handled at the top-level exception barrier. Those rare cases where the exception is a part of regular program logic are not something that the programmer will tend to miss, and would need the compiler to tell him. – Marko Topolnik Mar 21 '14 at 10:19
  • @MarkoTopolnik, I respectfully disagree. Coming from a `C` world, I can tell you that most programmers ignore error codes returned by functions, even if they're part of the "regular program logic". I get the fact that you don't like **any** exceptions, be they checked or unchecked, but that doesn't mean the rest of all have to follow suit. As for handling all exceptions at a "top-level exception barrier", it sounds to me like you're just catching unrecoverable exceptions. You cannot do anything meaningful at a high-level with most recoverable exceptions. – Gili Mar 21 '14 at 22:04
  • @MarkoTopolnik, for example: if a user tries opening a non-existent file it would make no sense to handle it at some "top level exception-barrrier". You'd need to handle it at the deepest level and prompt the user for a new path. – Gili Mar 21 '14 at 22:06
  • 3
    @Gili Your example is precisely that *rare case* which I mention. On the server side such cases are even less frequent. As for your comparison with C, exceptions -- unlike error codes -- can only be ignored *explicitly*, with empty catch-blocks. Funnily enough, that's exactly what happens when devs are forced to do something about checked exceptions. Your statement that I *don't like* exceptions sounds like you're trying to be funny, but I'm sorry for missing the humor. – Marko Topolnik Mar 21 '14 at 22:09
  • @Gili At the exception barrier we handle exceptions which break the unit of work---and most do. If any step that needs to be taken fails, the unit of work has failed as well. – Marko Topolnik Mar 21 '14 at 22:11
  • @MarkoTopolnik, what is rare for you is not rare for others. It could very well be that the exceptions you deal with are unrecoverable or unexpected. That's fine. But there are a whole host of cases where this isn't the case. If you only want to use unchecked exceptions, that is your right. I would point out that server-side applications are much less likely to be interactive than client-side applications, and as such exceptions are much less likely to be recoverable. That said, try developing client-side applications for a couple of years and your experience will be exactly the opposite. – Gili Mar 22 '14 at 03:04
  • 3
    @gili I have extensive experience developing at both sides and, although there is a slight difference, the ratio of all exceptions vs. those that need to be caught early is still very large. For example, user input is *validated* before acting upon it, and that includes such checks as whether a file exists using `file.exists()`, which makes a subsequent `FileNotFoundException` a strange and unexpected occurrence. – Marko Topolnik Mar 22 '14 at 06:35
  • @MarkoTopolnik, allow me to introduce you to the possibility of race conditions and I/O errors when reading a file. It doesn't matter how rare an exception is. It matters that it can and *does* happen in the wild. Having your program crash because of the WIFI connection went down in mid-read is hardly a formula for writing reliable software. Again, you are free to avoid handling such errors if you wish, but implying that everyone should do the same is a different story. – Gili Mar 22 '14 at 13:33
  • 2
    @Gili Now you have invented your own claim and assigned it to me. Where do I claim the application should *crash* in the face of an exception? I said *the current unit of work will be aborted*. Now you tell me, how should the current unit of work *continue* when the WiFi connection is lost? If you have some heuristics in mind that will keep retrying until the connection is reestablished and so on, then that is indeed an example of a *special case* where exceptions are handled within the unit of work. For most purposes such heuristics are not worth it and simply aborting is good enough. – Marko Topolnik Mar 22 '14 at 14:24
  • 2
    @MarkoTopolnik, I withdraw my comment about the software crashing in the face of the WIFI connection going down. We could have a very interesting debate on this topic, but Stackoverflow's comment system doesn't work well for this kind of discussion (comments are too short, and too asynchronous). Let's agree to disagree for now ;) – Gili Mar 23 '14 at 15:58
  • 1
    @Gili surely this specific example is not recoverable anyway. In pretty much any system I have seen, if DriverManager.getConnection fails, something is seriously wrong. If you're in a webapp, the odds are the configuration is incorrect. If you're in a GUI app, the odds are you're using an embedded database and hard-coding the path. So I would never expect getConnection to throw - yet the API forces us to catch it for no good reason. Checked exceptions may have had a theoretical use case, but their inconsistent application in the JRE has made them worse than useless. – Hakanai Dec 07 '14 at 23:03
  • @Trejkaz, you're using a strawman argument. If you read http://stackoverflow.com/questions/27578/when-to-choose-checked-and-unchecked-exceptions/19061110#19061110 you'll see I highlight SQLException as one of the most abused exceptions around. Checked exceptions have a place, but SQLException is not it. – Gili Dec 09 '14 at 00:08
  • 1
    @Gili A "strawman argument" is an argument where I construct one example of a case where my viewpoint is correct and then use it to imply that my viewpoint is correct. The code fragment above uses SQLException, so I believe that in this situation, I am not using a strawman argument as I did not provide the example. Note that I did not say that checked exceptions are useless. I specifically said that checked exceptions **in Java** are worse than useless. Which is still correct. – Hakanai Dec 09 '14 at 02:27
  • @Trejkaz, not all exceptions are `SQLException` yet you seem to be extrapolate from the abusive usage of `SQLException` to saying all checked exceptions in Java are "worse than useless". I am saying that the first point does not imply the second point. – Gili Dec 09 '14 at 06:21
  • 1
    @Gili Okay, let's flip this around. Can you even name one checked exception in the JRE which is applied consistently and correctly throughout the JRE? I would be interested in hearing your counter-example, because I have not actually discovered a single one yet. (And anyway, I didn't extrapolate from abusive usage of one exception. I extrapolated from a 15 year experience of running into all the other cases where they couldn't seem to get it right.) – Hakanai Dec 11 '14 at 06:09
  • @Trejkaz `java.io.FileNotFoundException` comes to mind. As do any I/O operations where it's reasonable to retry on failure (or ask the user for an alternative file). `SQLException` typically maps to programming errors, but `IOException` typically maps to runtime errors outside the programmer's control (and in many cases, these failures are recoverable). – Gili Dec 12 '14 at 06:31
  • 1
    I disagree with that case. When the user enters a file path, it is _expected_ they they can enter an invalid path. Since there is a general rule not use exceptions for normal flow control, in this situation I would check that the file exists before opening it. Therefore, having a FileNotFoundException on constructors of stream classes is just a nuisance to me - a second place I will have to catch. – Hakanai Dec 15 '14 at 22:36
  • @Trejkaz the problem is that you can't have any guarantee that, after you've checked the file existed and you decide to open it, it still exists. Yo need to take race conditions into account. – JB Nizet Dec 15 '14 at 22:39
  • 1
    @JBNizet Sure, but I would argue that sort of condition to be relatively rare and thus not something I should have to take care of with boilerplate. :( – Hakanai Dec 16 '14 at 01:18
  • @JBNizet After having checked that "foo.xml" exists, many things can go wrong. The file disappearing is what I'd fear least, there may be problems with missing read permissions, failing disk, invalid content or bugs in the parser... and none of the problems can be really solved. All of them must be handled somehow, and I can't see any outstanding solution for `FileNotFoundException` (offering the user to open "bar.json" instead doesn't count :D). *All* of the problems may or may not be still present when you retry. – maaartinus May 25 '17 at 03:26
  • Do you know if this already implemented in Spring / apache commons etc? I realize it's a small piece of code but still :D – XZen Nov 24 '17 at 16:23
  • It is strange that @JBNizet comes up with a clearly case that proves the point against checked exceptions. If forced to catch an exception after checking for the files existence, many programmers would consume the exception without logging (They DO, I've seen it) when they would have ignored it allowing it to be logged if it had been unchecked. Consuming a single checked exception without handling it can cost more developer time than almost any other problem... I've actually spent a full week tracking one of those that would have taken minutes if it had been unchecked and therefore logged. – Bill K Jan 24 '18 at 17:30
34

In the lambda mailing list this was throughly discussed. As you can see Brian Goetz suggested there that the alternative is to write your own combinator:

Or you could write your own trivial combinator:

static<T> Supplier<T> exceptionWrappingSupplier(Supplier<T> b) {
     return e -> {
         try { b.accept(e); }
         catch (Exception e) { throw new RuntimeException(e); }
     };
}

You can write it once, in less that the time it took to write your original e-mail. And similarly once for each kind of SAM you use.

I'd rather we look at this as "glass 99% full" rather than the alternative. Not all problems require new language features as solutions. (Not to mention that new language features always causes new problems.)

In those days the Consumer interface was called Block.

I think this corresponds with JB Nizet's answer.

Later Brian explains why this was designed this way (the reason of problem)

Yes, you'd have to provide your own exceptional SAMs. But then lambda conversion would work fine with them.

The EG discussed additional language and library support for this problem, and in the end felt that this was a bad cost/benefit tradeoff.

Library-based solutions cause a 2x explosion in SAM types (exceptional vs not), which interact badly with existing combinatorial explosions for primitive specialization.

The available language-based solutions were losers from a complexity/value tradeoff. Though there are some alternative solutions we are going to continue to explore -- though clearly not for 8 and probably not for 9 either.

In the meantime, you have the tools to do what you want. I get that you prefer we provide that last mile for you (and, secondarily, your request is really a thinly-veiled request for "why don't you just give up on checked exceptions already"), but I think the current state lets you get your job done.

Edwin Dalorzo
  • 76,803
  • 25
  • 144
  • 205
  • 2
    Thanks for the reply. Frankly speaking, I hoped that lambda expressions will be checked-exceptions-friendly, and the universe of checked exceptions will pass by lambdas since they are purely a compiler-driven feature. But no luck. – Lyubomyr Shaydariv Mar 27 '14 at 18:19
  • 1
    @LyubomyrShaydariv I think the expert group struggled with several design issues. The need, requirement or constraint to keep backwards compatibility made things difficult, then we have other important issues like the lack of value types, type erasure and checked exceptions. If Java had the first and lacked of the other two the design of JDK 8 would have been very different. So, we all must understand that it was a difficult problem with lots of tradeoffs and the EG had to draw a line somewhere and make a decision. That may not always pleases us, but surely there will be workarounds suggested. – Edwin Dalorzo Mar 28 '14 at 15:04
  • Yes, but lacking both value types and true generics is caused with JVM legacy, despite the checked exceptions do not exist in runtime, and they are purely compiler-driven. Kotlin or Xtend do not have checked exceptions, so they do not force to catch an `IOException`, for example. For me, it's still not yet clear why the design team doesn't allow to omit the checked exceptions in lambda expressions. It would be nice to have an example scenario where omitting a checked exception in a lambda expression might break the expectations. – Lyubomyr Shaydariv Mar 28 '14 at 16:03
  • 3
    @LyubomyrShaydariv A functional interface is just like any other interface. You can implement it through a lambda expression or manually. If you would throw a checked exception within the implementation of an interface method that does not declare to throw that exception you are breaking the semantics of the programming language. You are throwing an exception not expected by the code dealing with implementations of the interface. I do not see that is OK. I will need a more elaborate example of your proposition for it to make sense to me. Maybe you should create another discussion for that. – Edwin Dalorzo Mar 28 '14 at 16:13
  • 2
    Well, so the only thing I currently see, if lambda expressions were checked-exceptions-friendly, is: `try { iDontHaveThrowsDeclared(x -> someIOOperation(x)) } catch ( IOException ) { ... }` won't compile, because `IOException` in the `catch` block is known to be a checked one and the `iDontHaveThrowsDeclared`doesn't have a `throws` clause. So yes, it breaks. – Lyubomyr Shaydariv Mar 28 '14 at 17:52
  • 1
    @EdwinDalorzo, to the user a Lambda Expression is like it does not have a function body, it is like it runs completely within the context of where the lambda expression is written. For the same reason, it seems natural to expect that the exception can be handled in that same context, outside the lambda expression, within the method. The problem is that the actual execution can happen at a much - much later point, in a totally different context, maybe as part of an API. We cannot expect an API to handle every conceivable checked Exception. Wrapping in an unchecked exception seems appropriate. – YoYo Sep 21 '14 at 18:10
5

September 2015:

You can use ET for this. ET is a small Java 8 library for exception conversion/translation.

With ET you can write:

super(() -> et.withReturningTranslation(() -> DriverManager.getConnection(url)), maxConnections);

Multi line version:

super(() -> {
  return et.withReturningTranslation(() -> DriverManager.getConnection(url));
}, maxConnections);

All you need to do before, is creating a new ExceptionTranslator instance:

ExceptionTranslator et = ET.newConfiguration().done();

This instance is 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)

Community
  • 1
  • 1
micha
  • 47,774
  • 16
  • 73
  • 80
5

We developed an internal project in my company that helped us with this. We decided to went public two months ago.

This is what we came up with:

@FunctionalInterface
public interface ThrowingFunction<T,R,E extends Throwable> {
R apply(T arg) throws E;

/**
 * @param <T> type
 * @param <E> checked exception
 * @return a function that accepts one argument and returns it as a value.
 */
static <T, E extends Exception> ThrowingFunction<T, T, E> identity() {
    return t -> t;
}

/**
 * @return a Function that returns the result of the given function as an Optional instance.
 * In case of a failure, empty Optional is returned
 */
static <T, R, E extends Exception> Function<T, Optional<R>> lifted(ThrowingFunction<T, R, E> f) {
    Objects.requireNonNull(f);

    return f.lift();
}

static <T, R, E extends Exception> Function<T, R> unchecked(ThrowingFunction<T, R, E> f) {
    Objects.requireNonNull(f);

    return f.uncheck();
}

default <V> ThrowingFunction<V, R, E> compose(final ThrowingFunction<? super V, ? extends T, E> before) {
    Objects.requireNonNull(before);

    return (V v) -> apply(before.apply(v));
}

default <V> ThrowingFunction<T, V, E> andThen(final ThrowingFunction<? super R, ? extends V, E> after) {
    Objects.requireNonNull(after);

    return (T t) -> after.apply(apply(t));
}

/**
 * @return a Function that returns the result as an Optional instance. In case of a failure, empty Optional is
 * returned
 */
default Function<T, Optional<R>> lift() {
    return t -> {
        try {
            return Optional.of(apply(t));
        } catch (Throwable e) {
            return Optional.empty();
        }
    };
}

/**
 * @return a new Function instance which wraps thrown checked exception instance into a RuntimeException
 */
default Function<T, R> uncheck() {
    return t -> {
        try {
            return apply(t);
        } catch (final Throwable e) {
            throw new WrappedException(e);
        }
    };
}

}

http://github.com/pivovarit/throwing-function

Grzegorz Piwowarek
  • 13,172
  • 8
  • 62
  • 93
  • Is this actually the complete implementation? you are lacking any example of how to use it. – Al Ro Jul 19 '23 at 17:11
4

Have you considered using a RuntimeException (unchecked) wrapper class to smuggle the original exception out of the lambda expression, then casting the wrapped exception back to it's original checked exception?

class WrappedSqlException extends RuntimeException {
    static final long serialVersionUID = 20130808044800000L;
    public WrappedSqlException(SQLException cause) { super(cause); }
    public SQLException getSqlException() { return (SQLException) getCause(); }
}

public ConnectionPool(int maxConnections, String url) throws SQLException {
    try {
        super(() -> {
            try {
                return DriverManager.getConnection(url);
            } catch ( SQLException ex ) {
                throw new WrappedSqlException(ex);
            }
        }, maxConnections);
    } catch (WrappedSqlException wse) {
        throw wse.getSqlException();
    }
}

Creating your own unique class should prevent any likelihood of mistaking another unchecked exception for the one you wrapped inside your lambda, even if the exception is serialized somewhere in the pipeline before you catch and re-throw it.

Hmm... The only thing I see that's a problem here is that you are doing this inside a constructor with a call to super() which, by law, must be the first statement in your constructor. Does try count as a previous statement? I have this working (without the constructor) in my own code.

GlenPeterson
  • 4,866
  • 5
  • 41
  • 49
  • Thank you for reply. I would really like to prevent explicit `try/catch`ing in lambda expressions because `try/catch` blocks look ugly making the lambdas ugly too. I guess there are at least two reasons of why it cannot work like that so far: 1) the history of Java itself; 2) a method, that's invoked with a lambda expression having methods with `throws` invocations inside, probably should be "automatically" declared as "`throws` _SomeEx_", even if the method is declared without any `throws` or it declares to throw exception of another type rather than could be propagated from the lambda. – Lyubomyr Shaydariv Aug 09 '13 at 04:00
  • 3) If it could "swallow" checked exceptions, I think, then it might break your expectations for a checked exception or unchecked exception you might expect to catch in any caller outside. For example, you could expect to catch `IOException` for currently illegal code like `list.forEach(p -> outputStream.write(p.hashCode()))` (`write()` throws `IOException`), but you'd probably couldn't do it, because `Iterable.forEach()` is not declared as a method throwing `IOException`, so a compiler cannot know of these intentions. Sometimes checked exceptions are really harmful... – Lyubomyr Shaydariv Aug 09 '13 at 04:16
  • I agree. It would be overkill to provide a second set of java.util.function classes that declare that they throw a (checked) Exception. Especially since we'd need two versions of every method with a function parameter - one that throws and one that doesn't. That goes a long way toward explaining why Scala doesn't have checked exceptions (only unchecked). Java 8 is a copy of Scala's lambdas with a `->` instead of `=>`. I wonder if Martin Odersky suggested any of this while he was working at Sun? I hope Java 9 includes immutable versions of most of their API classes. – GlenPeterson Aug 09 '13 at 15:09
1

Wrapping the exception in the described way does not work. I tried it and I still get compiler errors, which is actually according to the spec: the lambda expression throws the exception which is incompatible with the target type of the method argument: Callable; call() does not throw it so I can not pass the lambda expression as a Callable.

So basically there is no solution: we are stuck with writing boilerplate. The only thing we can do is voice our opinion that this needs fixing. I think the spec should not just blindly discard a target type based on incompatible thrown exceptions: it should subsequently check whether the thrown incompatible exception is caught or declared as throws in the invoking scope. And for lambda expressions that are not inlined I propose we can mark them as silently throwing checked exception (silent in the sense that the compiler should not check, but the runtime should still catch). let's mark those with => as opposed to -> I know this is not a discussion site, but since this IS the only solution to the question, let yourself be heard and let's change this spec!

  • The wrapping is described just like it could imitate a checked-exception-less `Supplier` instead of `Callable` -- that is a surrogate way and it works for most cases that I was faced with. I personally would change the behavior of lambda expressions / functional interfaces for checked exceptions. But I have doubt that the lambda-dev team will agree to change that behavior for lambda's. Unfortunately Java checked exceptions are good by intention, but harmful in practice. This is similar to wrapping a checked exception into `RuntimeException` within `try/catch` in every method. – Lyubomyr Shaydariv Jan 15 '13 at 17:35
  • Well, there is a way to kind of genericly wrap the checked exception which is slightly more eloborate then described, see my upcoming answer. But still, I agree with you that our programming lives would be better if the compiler would work a bit harder and allow us to throw checked exceptions in our lambdas. As it stands we are deprived of catching specific checked exceptions that occur there, forcing us into ugly cumbersome coding. yuck! – Waldo auf der Springe Jan 16 '13 at 22:21
  • By the way, you can try to suggest your idea for simplified checked exceptions handling to lambda-dev team via their mailing list. If they approve your email (not idea itself) -- you might know their pros and cons for changing the spec, and probably personal ideas and thoughts by Brian Goetz too. – Lyubomyr Shaydariv Jan 17 '13 at 09:45
  • Thank you for the tip. I tried that actually, but the suggestion has completely been ignored. The reactions of contributions made regarding checked exceptions don't look too positive. Nevertheless I hope that people that share these concerns speak out, while there is still some time to repair it. The java lambda looks so good that this deserves fixing. – Waldo auf der Springe Jan 18 '13 at 20:46
1

Paguro provides functional interfaces that wrap checked exceptions. I started working on it a few months after you asked your question, so you were probably part of the inspiration for it!

You'll notice that there are only 4 functional interfaces in Paguro vs. the 43 interfaces included with Java 8. That's because Paguro prefers generics to primitives.

Paguro has single-pass transformations built into its immutable collections (copied from Clojure). These transforms are roughly equivalent to Clojure transducers or Java 8 streams, but they accept functional interfaces that wrap checked exceptions. See: the differences between Paguro and Java 8 streams.

GlenPeterson
  • 4,866
  • 5
  • 41
  • 49
  • That's cool stuff, and it's nice to be a part of your inspiration. :) Three years after the post I can't completely refuse the exceptional twins of the standard functional interfaces. I'm pretty sure it's just because I'm too lazy to create yet another business logic interface. I usually never combine them with streams processing, and I think that checked exceptions can be a great option especially for cross-layer communucation. – Lyubomyr Shaydariv Oct 29 '15 at 19:58
  • 1
    I think now, over those years, that my initial question was wrong from the design perspective: why did I want a `Supplier` instance to be a factory at all? Now I think that that dirty constructor in the post should just delegate something like a `IConnectionFactory` that declares an `SQLException` to be thrown just to clearly reveal the intentions of such an interface that might be more or less easily extended in the future. – Lyubomyr Shaydariv Oct 29 '15 at 20:04
1

You can throw from your lambdas, they just have to be declared "with your own way" (which makes them, unfortunately, not re-usable in standard JDK code, but hey, we does what we cans).

@FunctionalInterface
public interface SupplierIOException {
   MyClass get() throws IOException;
}

Or the more generic-ized version:

public interface ThrowingSupplier<T, E extends Exception> {
  T get() throws E;
}

ref here. There is also a mention of using "sneakyThrow" to not declare the checked exceptions, but then still throw them. It that hurts my head a bit, maybe an option.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
1

jOOλ is a library that supports wrapping all sorts of functional interfaces throwing checked exceptions into equivalent JDK functional interfaces. For example:

// Wraps the checked exception in an unchecked one:
Supplier<Class<?>> supplier = Unchecked.supplier(() -> Class.forName("com.example.X"));

// Re-throws the checked exception without compile time checking:
Supplier<Class<?>> supplier = Sneaky.supplier(() -> Class.forName("com.example.X"));

I've made some more examples in this blog post here. Disclaimer: I made jOOλ

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509