Meta tags:
description= How to repackage checked exceptions that get thrown in a Java stream pipeline so that they can be thrown without the compiler complaining about it.;
keywords= stream exception;
Headings (most frequently used words):
in, exception, repackaging, exceptions, streams, setting, the, scene, reflection, wrap, unchecked, sneaky, throw, lift,
Text of the page (most frequently used words):
the (80), #exception (50), that (49), java (40), stream (30), this (28), you (24), #exceptions (19), throw (19), user (19), not (18), checked (18), parse (18), and (17), streams (17), project (15), throws (14), but (13), function (13), return (13), with (13), catch (12), there (11), parseexception (11), compiler (10), have (10), for (10), can (10), strings (9), method (8), one (8), liftexception (8), might (8), pipeline (7), will (7), because (7), sneaky (7), thrown (7), checkedfunction (7), out (7), map (7), string (7), try (7), unchecked (7), repackaging (7), handle (6), methods (6), get (6), even (6), into (6), would (6), way (6), hideexception (6), post (6), all (5), then (5), like (5), does (5), wrap (5), different (5), use (5), reflection (5), could (5), problem (5), makes (5), about (5), element (5), community (5), code (5), junit (5), want (4), though (4), how (4), without (4), still (4), declare (4), only (4), more (4), well (4), bomb (4), userstrings (4), your (4), too (4), when (4), sneakythrow (4), generics (4), apply (4), something (4), various (4), clean (4), license (3), stackoverflow (3), note (3), what (3), next (3), let (3), aware (3), interfaces (3), declares (3), than (3), works (3), never (3), are (3), some (3), handled (3), they (3), hard (3), make (3), extends (3), lift (3), actually (3), good (3), should (3), declared (3), answer (3), instead (3), uses (3), case (3), look (3), first (3), which (3), point (3), documentation (3), new (3), many (3), interface (3), solutions (3), complaining (3), techniques (3), setting (3), scene (3), follow (3), share (3), lambda (3), pioneer (3), demos (3), core (3), privacy (2), rss (2), github (2), twitch (2), youtube (2), discord (2), mastodon (2), bluesky (2), find (2), often (2), spot (2), least (2), being (2), runtime (2), given (2), them (2), needs (2), another (2), allow (2), soon (2), things (2), either (2), common (2), both (2), exactly (2), before (2), think (2), hidden (2), list (2), println (2), system (2), foreach (2), returns (2), pretty (2), useful (2), call (2), put (2), block (2), example (2), where (2), now (2), callers (2), don (2), terminal (2), operation (2), very (2), unhandled (2), compile (2), consider (2), really (2), seen (2), such (2), little (2), may (2), unfortunately (2), technique (2), handling (2), error (2), did (2), any (2), its (2), throwable (2), suppresswarnings (2), whether (2), has (2), easier (2), bad (2), other (2), down (2), runtimeexception (2), repackage (2), uncheckexception (2), come (2), functional (2), public (2), assume (2), entire (2), operations (2), main (2), goal (2), cases (2), active (2), platforms (2), watch (2), space (2), notified (2), publish (2), content (2), talks (2), libfx (2), record (2), args (2), var (2), turn (2), year (2), tools (2), switch (2), serialization (2), records (2), valhalla (2), panama (2), loom (2), leyden (2), amber (2), performance (2), patterns (2), pattern (2), matching (2), optional (2), ramp (2), migration (2), meta (2), maven (2), libraries (2), javafx (2), basics (2), j_ms (2), dop (2), deprecation (2), libs (2), collections (2), architecture (2), tags (2), javascript (2), contact, imprint, these, approaches, mean, stop, processing, yielding, results, unless, those, achieved, side, effects, returning, article, tackles, investigating, aborting, gets, somewhere, utitility, recognize, shown, two, half, ways, immediately, drawback, namely, used, far, single, problematic, derive, supertype, likely, additional, great, options, sebastian, millies, pointed, said, occasionally, risk, colleague, takes, apart, during, refactoring, arming, undeclared, tolist, collect, alternatively, containing, someone, who, body, abundantly, clear, course, see, part, arguably, situation, confusing, expecting, surprised, remember, same, why, helpful, understand, was, surprises, consumers, once, overcame, surprise, latter, nice, experiment, worded, stronger, needless, say, care, everybody, must, appear, shows, ranks, extremely, google, looking, fairness, contains, disclaimer, afraid, ignored, wow, sucks, won, work, operates, under, assumption, none, filter, rethrow, everything, else, risky, move, hides, goes, much, further, extra, defuse, properly, ever, clause, err, promised, trick, throwing, declaring, rethrows, sneakily, using, lombok, annotation, sneakythrows, fix, whole, thing, confuse, silence, remaining, complaints, finally, aborts, occurs, deciding, tough, consuming, requirements, final, consumer, communicated, tests, ignore, feels, hiding, prefer, anyway, enticing, hand, value, distinction, between, expect, wrong, input, implementation, errors, sent, shivers, spine, maybe, throwables, interruptedexception, calling, thread, interrupt, simple, special, astute, readers, observed, easy, transform, just, know, away, surprising, yes, remains, allows, assign, type, generic, handy, later, functionalinterface, introduce, while, regard, api, incompatibility, been, overcome, design, write, longer, explaining, short, version, pleasant, combine, laziness, eventually, leads, reference, text, userstring, static, class, having, parameters, values, within, scope, following, assessments, trying, users, underlying, scenario, every, frequent, encountered, form, intermediate, stops, propose, ideally, establish, terminology, discussions, also, comment, suggestions, adding, own, assessment, secondary, hope, distract, from, getting, ideas, couple, years, old, edge, yet, develop, arsenal, pipelines, accept, implementations, obviously, tension, here, developers, across, toc, table, contents, lic, artist, dev, source, src, stab, explores, 2017, slides, upcoming, past, schedule, recordings, virtual, threads, vector, structured, concurrency, lilliput, galahad, babylon, openjdk, conversation, book, club, videos, jms, newsletter, blog, posts, testing, rant, jigsaw, jdeps, impulse, default, lang, review, comments, words, site, better, enabled, nipafx,
Text of the page (random words):
repackaging exceptions in streams nipafx this site works well without javascript but it works even better with javascript enabled bluesky mastodon discord youtube twitch github stackoverflow rss words tags architecture clean code clean comments code review collections community core lang core libs default methods deprecation documentation dop generics impulse j_ms java 10 java 11 java 12 java 13 java 16 java 17 java 18 java 20 java 23 java 24 java 25 java 26 java 27 java 8 java 9 java basics java next javafx jdeps js junit 5 junit pioneer lambda libfx libraries maven meta migration on ramp optional pattern matching patterns performance project amber project jigsaw project leyden project loom project panama project valhalla rant record args records reflection serialization streams switch techniques testing tools turn of the year var blog posts newsletter the jms videos tags ai architecture book club clean code collections community conversation core libs deprecation documentation dop generics j_ms java 10 java 11 java 12 java 16 java 17 java 18 java 19 java 21 java 22 java 23 java 24 java 25 java 26 java 8 java 9 java basics java next javafx junit 5 junit pioneer lambda libraries maven meta migration on ramp openjdk optional pattern matching patterns performance project amber project babylon project galahad project leyden project lilliput project loom project panama project valhalla records reflection serialization streams structured concurrency switch techniques tools turn of the year var vector virtual threads recordings streams schedule code demos demos demos junit pioneer record args libfx talks my talks past upcoming slides about about me license privacy 2017 02 13 repackaging exceptions in streams post clean code java 8 lambda streams my first stab at exception handling in java streams explores how to repackage checked exceptions so that they can be thrown without the compiler complaining about it src source dev artist lic license repackaging exceptions in streams table of contents setting the scene repackaging exceptions in streams wrap in unchecked exception sneaky throw exception lift exception reflection share follow share this post with your community i m active on various platforms watch this space or follow me there to get notified when i publish new content toc setting the scene repackaging exceptions in streams wrap in unchecked exception sneaky throw exception lift exception reflection s f share this post with your community i m active on various platforms watch this space or follow me there to get notified when i publish new content java 8 is a couple of years old but there are still use cases not even edge cases that the community did not yet develop a good arsenal of solutions for how to handle checked exceptions in stream pipelines is one such problem the functional interfaces various stream operations accept do not allow implementations to throw checked exceptions but many methods we might want to call do obviously there s a tension here which many developers have come across my main goal is to propose various solutions and ideally to establish a common terminology that makes discussions easier i will also comment on my suggestions adding my own assessment of how useful i find them this is secondary though and i hope that it does not distract from the main goal getting the ideas out there this first post will look into repackaging exceptions so that the compiler stops complaining setting the scene the underlying scenario is something every frequent user of streams has encountered in one form or other a method you would like to use in one of stream s intermediate operations throws a checked exceptions in this post i will assume that you are trying to parse a stream of strings to a stream of users stream user parse stream string strings return strings map user parse if you re not down with having streams as parameters or return values assume the entire stream pipeline would be within the method s scope the following techniques apply either way but some of the assessments would be different if you handled the entire stream on the spot unfortunately user parse can throw a parseexception public class user public static user parse string userstring throws parseexception this leads to the compiler complaining about unhandled exception java text parseexception for the method reference user parse what to do now before we look into solutions for this problem i want to point something out i do not regard the stream api s incompatibility with checked exceptions as something that could ve been overcome with a different design at some point i may write a longer post explaining that but the short version is this if the functional interface methods could throw checked exceptions there would be no pleasant way to combine that with streams laziness as it is the terminal operation that will eventually throw that exception but we can make good use of a function that can throw exceptions so let s introduce that interface while we re at it functionalinterface interface checkedfunction t r ex extends exception r apply t element throws ex this allows us to assign user parse to a checkedfunction string user parseexception note that the type of the exception is generic which will come in handy later repackaging exceptions in streams so do you really have to handle the exceptions could you not just i don t know make the problem go away the surprising answer is yes you can whether you should remains to be seen wrap in unchecked exception given a function that throws a checked exception it is pretty easy to transform it into one that throws an unchecked one instead stream user parse stream string strings return strings map uncheckexception user parse t r function t r uncheckexception checkedfunction t r exception function return element try return function apply element catch exception ex many astute readers have observed that this catch is too simple it should special case runtimeexception to not repackage interruptedexception calling thread interrupt and maybe even catch all throwables throw new runtimeexception ex this is actually not too bad and if you prefer unchecked exceptions anyway then this is all the more enticing if on the other hand you value the distinction between checked exceptions for things you expect can go wrong like bad input for example and unchecked exceptions for implementation errors then this will sent shivers down your spine in any case the final consumer of the stream has to be aware that the exception could be thrown which at this point needs to be communicated with tests or documentation both easier to ignore than the compiler it feels a little like hiding a bomb in the stream finally note that this aborts the stream as soon as the first error occurs something that might or might not be ok deciding whether it is ok can be tough if the method returns a stream instead of consuming it because different callers might have different requirements sneaky throw exception another way to fix this whole thing is to sneaky throw the exception this technique uses generics to confuse the compiler and suppresswarnings to silence its remaining complaints stream user parse stream string strings return strings map hideexception user parse t r function t r hideexception checkedfunction t r exception function return element try return function apply element catch exception ex return sneakythrow ex suppresswarnings unchecked e extends throwable t t sneakythrow throwable t throws e throw e t err what as promised the method sneakythrow uses generics to trick the compiler into throwing a checked exception without declaring it then hideexception uses that to catch any exception the checkedfunction might throw and rethrows it sneakily in case you re using lombok have a look at its sneakythrows annotation i consider this a very risky move for one it still hides a bomb in the stream it goes much further though and makes that bomb extra hard to defuse properly did you ever try to catch a checked exception that is not declared with a throws clause try userstrings stream map hideexception user parse foreach system out println compile error because parseexception is not declared as being thrown catch parseexception ex handle exception won t work because the compiler operates under the assumption that none of the methods actually throw a parseexception instead you d have to catch exception filter out parseexception and rethrow everything else wow that sucks unfortunately this technique shows up in a stackoverflow answer that ranks extremely well on google when looking for java stream exception handling in all fairness the answer contains a disclaimer but i am afraid it might get ignored too often needless to say this should be handled with care and everybody on the project must be aware that a checked exception may appear where it is not declared but as we have seen there is no good way to declare catch such an exception so i would have worded that a little stronger it s a nice experiment but never actually do it if you really want to throw wrap in a runtime exception lift exception the problem with sneaky throw was that it surprises consumers of the stream and makes it hard to handle that exception even once they overcame that surprise for the latter at least there is a way out consider this function t r ex extends exception function t r liftexception checkedfunction t r ex function throws ex return hideexception function it does exactly the same as hideexception but it declares that it throws ex why would that be helpful because this way you can use it to make the compiler understand that a checked exception might get thrown stream user parse stream string strings return strings does not compile because liftexception throws parseexception but it is unhandled map liftexception user parse the problem is and the body of liftexception makes that abundantly clear that it does of course not throw an exception so in an example like this where we see only part of the pipeline it arguably makes the situation even more confusing now callers of parse might put it into a try catch block expecting to have handled the exception well if they don t think too hard about it and then still get surprised when the terminal operation throws that very exception remember it is hidden with sneakythrow if you are someone who never returns streams though liftexception can be pretty useful with it some call in your stream pipeline declares to throw a checked exception so you can put it all into a try catch block try userstrings stream map liftexception user parse foreach system out println catch parseexception ex handle exception alternatively the method containing the pipeline could declare that it throws the exception list user parse list string userstrings throws parseexception return userstrings stream map liftexception user parse collect tolist but as i said before i think this only works well if you never return streams because if you do even only occasionally there is a risk that you or a colleague takes the pipeline apart during a refactoring arming the bomb that is an undeclared checked exception hidden in a stream there is another drawback that sebastian millies pointed out namely that the interfaces and methods used so far only allow a single exception as soon as a method declares more than one checked exception things get problematic either you let java derive a common supertype likely to be exception or you declare additional checkedfunction interfaces and liftexception methods for more than one exception both not exactly great options reflection given a method that throws a checked exception i have shown you two and a half different ways to use them in a stream if the exception needs to be thrown immediately wrap the checked exception in a runtime exception sneaky throw the checked exception so that the compiler does not recognize it being thrown still sneaky throw but let the utitility function declare the exception so that the compiler is at least aware that it gets thrown somewhere note that all of these approaches mean that the stream pipeline will stop processing then and there yielding no results unless those achieved by side effects i find often that is not what i want to do though because i do like returning streams the next article tackles this by investigating how to handle exceptions on the spot without aborting the pipeline bluesky mastodon discord youtube twitch github stackoverflow rss imprint privacy contact license
|