Checked exceptions: Java's biggest mistake (2014) - <AUTHOR> http://literatejava.com/exceptions/checked-exceptions-javas-biggest-mistake/ <comment><USER4> I like checked exceptions. Yes, sometimes (especially in the oldest APIs when they were still figuring this stuff out), they were overused but mostly I think they encourage developers to really think about what happens in the failure case.

I notice this especially with less experienced developers and remote calls - <USER2> lot of JS code I've reviewed in the past assumes the remote call will always work, yet Java code from the _same_ developer will almost always correctly handle the situation, simply because the exception is explicitly required to be handled.

<comment><USER5> Right.

They don't just "encourage" developers to consider error paths, they "force" them to do so.

The concept of checked exceptions is very sound, as is the more general concept of compiler enforced error checking. Very, very few languages have that (only Java and Kotlin in the mainstream league).

Languages with a solid implementation of algebraic data types offer a good first step in that direction but they still require users to manually bubble and compose monadic values, which introduces an unnecessary, and sometimes intractable, level of obfuscation and boiler plate.

All other languages provide weaker approaches to this concept that are library enforced, not language enforced, and therefore more prone to being overlooked since they require discipline from the developer.

<comment> augusto-moura You are not forced per se, and can have the same level of obsfucation. It's pretty common to find code ignoring exceptions or wrapping them in RuntimeExceptions, like:

      try {} catch (Exception e) {
        throw new RuntimeException(e);
      }

Also not doing nothing, or the famous catch and log

<comment><USER6> At which point it's super easy to identify in code review and slap the developer on the wrist.

I find these arguments that posit incompetent / ignorant developers as a hurdle a bit strange. If they are going to incompetently handle errors wrong when explicitly forced to handle them I can't even imagine how poor their code will be without any assistance from the compiler, and it seems awful to think that you will have no way to identify such poor handling on review - you're going to have to look up every function they call and check if it can return an error or not manually.

<comment><USER7> i.e. Go. Go can make sure you are aware that an error exists (often. linters do pretty good here too), but it does next to nothing to help you _handle it correctly_.

From personal experience: yes, little to no compiler help on errors takes an enormous amount of effort by both authors and reviewers (and future readers) to ensure correct handling. The vast majority of the time it's just `if err != nil { return err }`, which is very frequently sub-optimal. But without knowing the call in complete detail, you can't judge if that's true or not... and it may have changed since you last saw it.

IDEs help that kind of "is this optimal/correct" question quite a lot, but they can't verify it either. It's question-marks all the way down, unless you fully know all the code you call, which is often infeasible.

</comment></comment></comment></comment></comment><comment><USER8> Well... I will take the bullet and confess that I do like checked exceptions. When they are not miss|over used they transfer the enough required knowledge what is to be handled. You dont need to handle? Transfer to higher levels on stack. That is a great fit in my opinion for applications designed with especially fault tolerance futures and using many external components. Not saying that design of CE is perfect, they might be too broad that doesnt tell you exact handle case, so it will leave you in the dark or in a call chain of a()->b()-c()-d() there might be cases that b and c wouldnt need to have contract in their method signature maybe compiler would decide if exception is orphaned or needs to be handled.

<comment><USER9> I just read the article in diagonal. It doesn't seem to address the reason that I hate the thing: sometimes I don't care about errors at all. Let's say I'm writing a kleenex program to explore some feature. Not nice if you make me feel all kind of boilerplate.

Or maybe I just want to defer the error management to a higher level. Again busywork declaring exceptions.

<comment><USER10> If you don't care about exceptions just put,

try { //your code } catch (Exception e) { throw new RuntimeException(e); }

around it and you'll be fine.

The thing about Java is that the code lasts for a really long time because when it fails, it does so usually with an exception that points to the problem. When promises hang in NodeJS or memory corruption happens in C, it's much more annoying to track down problems.

<comment><USER11> There's also this magic function:

      private static <T extends Throwable> T sneakyThrow(Throwable ex) throws T {
         throw (T) ex;
      }

Due to generic type erasure, the entire throw clause gets erased so it looks like this method doesn't throw anything.

</comment></comment></comment></comment><comment><USER12> I don't really dislike the concept of checked exceptions, but the awful way they prevent the usage of functional interfaces and modern Java in general is pretty infuriating. Functional interfaces and code that uses them should have a generic way of being transparent to exceptions, but I'm not sure it can be done without breaking the language.

Nevertheless, I still believe that Java's biggest mistake is not checked exceptions, but the stupid distinction between primitive types and Objects (caused because all the cruft present in the latter would have make basic operations prohibitive in terms of performance, at least for early Java versions) and all the associated boxing. I have seen some extreme cases of performance degradation because of that (fortunately a refactor to use arrays solved the problem, but this is not always possible).

<comment><USER13> > Functional interfaces and code that uses them should have a generic way of > being transparent to exceptions

This irks me too. It's been a while but I believe the workaround is just to define your own (checked) FunctionE, SupplierE, ConsumerE functional interfaces. But maybe that causes other problems I've forgotten.

> the stupid distinction between primitive types and Objects

I also dislike the distinction between primitives and Objects. But I don't think your argument follows. Performance is why the distinction exists. Objects have the cruft and primitives don't.

<comment><USER14> >This irks me too. It's been a while but I believe the workaround is just to define your own (checked) FunctionE, SupplierE, ConsumerE functional interfaces. But maybe that causes other problems I've forgotten.

You can do that, but you need to do it for every exception type ): I'd love it if Java had templated exceptions.

>> the stupid distinction between primitive types and Objects

One of the slowest things I found out about C# was floats being objects and `a < b` (or something similar) being a stack about 7 levels deep.

<comment><USER15> > You can do that, but you need to do it for every exception type ): I'd love > it if Java had templated exceptions.

It does have them. You can write an interface with a type parameter `<E extends Throwable>` and declare functions inside it with `throws E`

<comment><USER16> You can do this, but it's not ideal. A function can list multiple exceptions in its throws clause, which share no common type except Throwable, but this combination of exception types can't be represented by a single type parameter (except for the common base type). So in a lot of cases, you lose information about the specific exceptions your function can throw, which limits the value of using checked exceptions.

</comment></comment></comment></comment></comment><comment><USER17> > The biggest argument against "checked" exceptions is that most exceptions > can't be fixed. The simple fact is, we don't own the code/ subsystem that > broke. We can't see the implementation, we're not responsible for it, and > can't fix it.

Here's what Oracle has to say:

> Here's the bottom line guideline: If a client can reasonably be expected to > recover from an exception, make it a checked exception. If a client cannot > do anything to recover from the exception, make it an unchecked exception.

[https://docs.oracle.com/javase/tutorial/essential/exceptions...](https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html)

\- checked exception for recoverable errors

\- unchecked exception for non-recoverable errors

So the argument that most errors can't be recovered from is _not_ a reason to abandon checked exceptions. It's a reason to reserve checked exceptions for those cases in which recovery is likely.

The main argument in this article appears to be based on a misunderstanding.

<comment><USER18> The argument is that an error that can be recovered from isn't an exception. It should handled with standard guards (bounds check, null check, format check, etc). There's no checked exception that can't be better solved with an if/then statement.

<comment><USER19> > The argument is that an error that can be recovered from isn't an exception. > It should handled with standard guards (bounds check, null check, format > check, etc). There's no checked exception that can't be better solved with > an if/then statement.

That's a philosophical position that is largely driven by the language (and I suppose the ecosystem around it). I happen to agree with that position, so I prefer languages like rust and go over java.

But I also know that if I try to fight the customs of the language I'm working in, it'll end in a lot of pain and unnecessary angst; so, if I find myself using Java, I grit my teeth and used checked exceptions.

<comment><USER18> Checked exceptions are optional in Java. If you look at a even an long- standing enterprise platform like Spring, there's almost no checked exceptions. I always make it a policy on Java projects to not allow checked exceptions and it's never a problem. Anything in the standard lib may have to be dealt with, but I don't allow commits with any throws declaration.

</comment></comment></comment></comment><comment><USER20> How would eliminating checked exceptions mitigate terrible API design?

I've never understood the angst. All the arguments reduce down to mitigating terrible abstractions.

The Correct Answer is better APIs. Mostly, that means don't pretend the network fallacies don't exist. Embrace them. Which generally means work closer to the metal.

I'll say it another way. The problem is EJB, ORMs, Spring, etc. The obfuscation layers.

Someone smarter than me will have to rebut the functional programming points. I'd just use a proper FP language. Multiparadigm programming is a strong second on the list of stuff you shouldn't do. (Metaprogramming is first.)

<comment><USER21> > How would eliminating checked exceptions mitigate terrible API design?

Any API which has used checked exceptions was made worse by those, because Java's checked exceptions are bad, and their use runs actively against good APIs. So not having them would have made the corresponding APIs less bad (not necessarily good, mind) by definition.

<comment><USER20> Thank you for replying. It helps me to better articulate my thinking. You're my Rubber Duck.

Why would network programming (I/O, persistence, etc) look any different whether the language was C, Java, GoLang or other?

Most of my code is error checking and handling. (And now logging too, which I'll ignore here.) Is this abnormal? (Being rhetorical.)

Plenty of noob code ignores errors. I sort of thought we all decided that was suboptimal. Java's response was checked exceptions.

The only argument I've ever heard that made any sense is the silliness of catching exceptions so far removed from the root cause that your code can't do anything about it.

So don't do that.

Really, why would any one design a system that way? Because network programming is messy? Because it'd be neat to compartmentalize the messiness?

I've been able to cleanly separate the value add business logic from real world messiness exactly one time. I was in control of the full stack, end to end. Imagine something like a useful BizTalk. I had been inspired by postfix. My engine would pass work to plugins, which didn't have to do any I/O of their own. My work anticipated serverless and AWS Lambda, if those programming frameworks (paradigms) were better designed.

It now occurs to me that the checked exception abolitionists are advocating _Happy Path Programming_.

The only other feasible Happy Path Programming strategy I know of is Erlang. I've only done an Erlang tutorial, nothing in prod, so this is just a guess.

<comment><USER22> > Most of my code is error checking and handling.

> Plenty of noob code ignores errors.

You can encode errors into the return type of the function to force people to deal with errors. Here's a good example:

      byte[] read() throws IOException
        // vs
      Optional<byte[]> read()

Both cases force the user to consider failure cases.

Checked exceptions are essentially modifying the return type already, just in a different syntax. It's inconvenient because the nonstandard syntax for the type doesn't work well with all the other return types. It's still a bit inconvenient to use the other option in Java though because there's no language level support for real tagged unions (sum type) (union type). [https://en.wikipedia.org/wiki/Tagged_union](https://en.wikipedia.org/wiki/Tagged_union)

The other class of not handling errors takes a bigger conceptual leap:

      void write(byte[]) throws IOException
        // vs
      Optional<Void> write(byte[])

The caller could just ignore the value in Java, so your criticism is still valid. However, you can force the caller to _never_ implicitly ignore return values. If the function 'throws' by returning a value, you have to explicitly ignore it:

      val _ = write(bytes);

If the function can't throw (i.e. the return type is strictly 'void'), then you don't have to do anything:

      write(bytes);

<comment><USER23> Optional<T> isn't a replacement for typed exceptions as you can't pass or inspect the error details.

<comment><USER22> That's correct. I used Optional because it's included in Java and it's simpler. With Optional I could explain handling the presence of errors, but not the inspection of errors.

A full replacement is the Result type (a specialized 'Either'): [https://doc.rust-lang.org/std/result/](https://doc.rust-lang.org/std/result/)

<comment><USER23> Yeah. Although, that has an explicit error type which is good and bad. The errors are consistent and known but you're restricted to throwing them together into a single type. I kind of like C#'s Task type where you can still use the catch block pattern matching if you want to. Maybe dropping the catch syntax is better though.

</comment></comment></comment></comment></comment></comment></comment><comment><USER24> Some checked exceptions make a lot of sense to try to catch and fix. FileNotFoundException is something my code can probably recover from - <USER3> asked for a file, it's not there, let me ask for a different file. Having a file reading method declare that it throws FileNotFoundException can be a helpful reminder to make sure you handle that possibility.

But then there are other types of checked exceptions that are almost certainly unrecoverable because they happen way down in some other third party code. And then you get the endless chain of "throws" all the way back up the code base.

<comment><USER25> > But then there are other types of checked exceptions that are almost > certainly unrecoverable because they happen way down in some other third > party code. And then you get the endless chain of "throws" all the way back > up the code base.

No you don't. When your code calls ThirdPartyAPI and it throws one of these checked exceptions that you know you can't recover from, you wrap it in a RuntimeException and rethrow. Then it's totally invisible to the rest of your code.

Likewise, you should never have a method that throws 10 kidns of checked exceptions. You should be writing your own custom exceptions that wrap downstream exceptions into forms that are useful for you and your code (or people who will use your code).

The biggest issue with checked exceptions is that people refuse to think through their unhappy paths.

<comment><USER26> Wrapping exceptions when re-throwing can be really useful. I think that this feature is often underused, especially by people who complain about checked exceptions.

<comment><USER27> E.g. Future wraps any Throwable in ExecutionException, which is a checked exception. But ExecutionExeption could wrap any exception! It may as well just throw Exception.

I really would have loved e.g. Future<Value,IOException|FooException>. Obviously it gets erased in the executor, but if your code holds on to it, it could maintain checked exceptions over the async boundary.

</comment></comment></comment></comment><comment><USER28> I've been using Scala quite heavily recently, having mostly used Haskell for years, with distant memories of Java. Scala allows Java methods to be called, but doesn't bother with checked exceptions, which has bitten me quite a few times.

My preferred style of error-handling is Option/Either, since I can implement the 'happy path' in small, pure pieces; plug them together with 'flatMap', etc.; then do error handling at the top with a 'fold' or 'match'.

Exceptions break this approach; but it's easy to wrap problematic calls in 'Try' (where 'Try[T]' is equivalent to 'Either[Throwable, T]').

The problem is that Scala doesn't tell me when this is needed; it has to be gleaned from the documentation, reading the library source (if available), etc.

I get that a RuntimeException could happen at any point; but to me the benefit of checked exceptions isn't to say "here's what you need to recover from", it's to say "these are very real possibilities you need to be aware of". In other words checked exceptions have the spirit of 'Either[Err, T]', but lack the polymorphism needed to make useful, generic plumbing. The article actually points this out, complaining that checked exceptions have to be handled/declared through 'all intervening code'; the same can actually be said of 'Option', or 'Either', or 'Try', etc., but the difference is that their 'intervening code' is usually calculated by the higher-order functions provided by Functor, Applicative, Monad, Traverse, etc.

It's similar to many developer's first experience of Option/Maybe: manually unwrapping them, processing the contents, wrapping up the result, then doing the same for the next step, and so on. It takes a while to grok that we can just map/flatMap each of our steps on to the last (or use 'for/yield', do- notation, etc. if available). It would be nice to have a similar degree of polymorphism for checked exceptions. Until then, I'd still rather have them checked (so I can convert them to a 'Try'), rather than getting no assistance from the compiler at all!

<comment><USER29> The right way isn't Either / Option (though it's a lot more viable with top- level type inference); it's unchecked exceptions.

Checked exceptions have bimodal usage, from the programmer POV. Either you care about the exception, and you deal with it very close to the throw point, or you don't care about the exception, and it should be handled far far away, across many stack frames.

The former isn't a problem. It's the right thing if e.g. you try to open a file and the file is missing, and you have reasonable error handling logic to retry, open a different file, replace the file and try again, whatever.

The latter is where the issue lies. If you're handling errors far away, then you're handling lots of different errors there, and you're not distinguishing between them, because there's too many different failure modes. You're most likely just in a loop logging errors, or terminating. You're too far from the cause of the exception to do anything specific with it, the context is lost. So the effort to transport the exception type throughout the call graph is pointless.

tl;dr: checked exceptions are fine near the leaf of the call graph, but are increasingly pointless towards the trunk.

<comment><USER30> `Result<T, dyn Error>` from Rust (since I'm not a Haskeler) is a result that can contain any error. Which is exactly what unchecked exceptions are.

Rust developers can fluently switch and convert between conrete `Result<T, SomeErrorEnumeration>` and `Result<T, dyn Error>`. It works beautifully. Libraries usually enumerate their errors (leafs), applications usually just throw everything to one universal error bag.

<comment><USER28> > Rust developers can fluently switch and convert between conrete `Result<T, > SomeErrorEnumeration>` and `Result<T, dyn Error>`

That's something different, since both cases tell you that errors might occur.

In Java we can do the following:

        public int concreteChecked() throws FileNotFound {
          if (bar) throw new FileNotFound();
          return 42;
        }

        public int polymorphicChecked() throws Exception {
          if (bar) throw new FileNotFound();
          return 42;
        }

        public Either<FileNotFound, int> concreteEither() {
          return bar? new Left(new FileNotFound()) : new Right(42);
        }

        public Either<Exception, int> polymorphicEither() {
          return bar? new Left(new FileNotFound()) : new Right(42);
        }

        public int unchecked() {
          if (bar) throw new RuntimeException(new FileNotFound());
          return 42;
        }

I think your 'Result' examples are like the third and fourth examples above: using a sum type, differing by whether the error is more/less specific.

The first and second use checked exceptions, again differing in whether the error is more/less specific. Importantly: these will refuse to compile if we don't have 'throws ...' in their signature.

The last example uses an unchecked exception: if we throw 'RuntimeException' (or a subclass), we don't need to put 'throws ...' in the signature, and hence the compiler won't keep tell us to put 'catch' block anywhere.

<comment><USER30> In Rust you can do `Result<T, dyn SomeErrorInterface>` as well, which makes it able to express everything exactly like Java can. It's just Rust community generally doesn't bother with the taxonomies of errors. You either get a concrete list, or "any error".

</comment></comment></comment></comment></comment><comment><USER31> I think checked exceptions are backwards. If you use a `throws` declaration the caller _must_ catch it. It quickly becomes quite onerous. (Especially if you come from the philosophy that an exception often means "abort this program - unless somebody catches this". In small programs you might just want it to crash early.) And even worse, it is not exhaustive. You can always get a RuntimeException or a NullPointerException from nowhere.

It would be great if they worked the other way around. Instead of _forcing the caller_ to catch an exception, they would _guarantee_ that no exception leaves a certain block.

So you would have a function

        void MyFunc() onlythrows IOException {
            first();
            second();
        }

And the compiler would statically guarantee that no other exception can leak out of it - because first and second have been marked `onlythrows IOException` or are "pure" and cannot throw at all.

For sure you'd need an escape hatch, like Rust's "unsafe". And it would not be very useful around legacy libraries. But it would be tremendously useful if you could drop a block like

       neverthrows NullPointerError { ... }

in your code and be sure that everything inside is null safe! I asked about this a few years ago on StackExchange [1] but so far I never heard about it anywhere else.

[1] [https://softwareengineering.stackexchange.com/questions/3497...](https://softwareengineering.stackexchange.com/questions/349775/different- kind-of-checked-exceptions-guarantee-to-only-throw-x)

<comment><USER32> > I think checked exceptions are backwards. If you use a `throws` declaration > the caller must catch it.

I'm not sure I I'm reading your comment right, but this is plainly false. Caller can add a throws declaration themselves and catch anything.

It seems to me that what you're advocating bears no difference at all with checked exceptions. The "unsafe" escape hatch is called RuntimeException. "throws" behaves exactly like your advocated "onlythrows".

The only actual difference you're proposing, AFAICS, is that you'd like java to handle nulls differently - and I think we can all agree on that.

<comment><USER31> > Caller can add a throws declaration themselves and catch anything.

You are right. I meant someone in the call stack has to catch, not the immediate caller.

That I mentioned null pointers is a red herring. I want to add a block that tells the compiler "prove that no exceptions (checked or unchecked, not even NPE)" can escape outside of this block!".

The escape hatch is about this: imagine you have a function that throws if the argument is odd, but you know you will only call it with an even number:

        void myFunc(int i) never_throws {
            swear_never_throws(NumberOddException) {
                throwsIfOdd(i*2);
            }
        }

(Apologies for the pseudo-code, I haven't made up a nice syntax.) If you mark your function that no exception can escape (not even an unchecked exception!), but the compiler sees that throwsIfOdd can throw NumberOddException, you must of course assert that what you are doing is OK.

</comment></comment></comment><comment> iso8859-1 The confusion regarding checked exceptions (which are fine, if not misused, see aazaa's answer) was made much worse by IDE's such as Eclipse, which would generate:

          catch (MyCheckedException e) {
            e.printStackTrace();
          }

This causes unreliable programs, since the programmer will initially only think about the successful path. Eventually, the exception will get thrown, and things will break in weird ways. They may not notice it quickly, because the stack trace will be buried in logs. Alternatively, if the IDE default has been

        throw new RuntimeException(e)

or something similar, which would crash the program, the programmer would have noticed it more easily. Of course, the program would still be broken, but better crash hard and violently than subtly and confusingly.

<comment><USER33> Checked exceptions are far from fine, and this has nothing to do with IDE code generation.

Monads are highly cumbersome, unwieldy, and difficult to use, but Haskell programmers put up with them anyways because they get specific value from them, being able to say things like:

* effect tracking * continuations * tracking which methods perform I/O * tracking errors

Java checked exceptions are like monads, but worse: they are even more unwieldy and interact poorly with the rest of the language. And yet, unlike monads in a language like Haskell, they provide practically zero value for their cost.

There is a reason no language since Java has copied checked exceptions as a feature, including C# which started as a direct rip-off of Java. There are better ways to encode errors into a method signature to try to force the caller to consider them than checked exceptions.

</comment></comment><comment> grey-area According to Gosling, including classes/inheritance was his biggest regret.

 _I once attended a Java user group meeting where James Gosling (Java 's inventor) was the featured speaker. During the memorable Q&A session, someone asked him: "If you could do Java over again, what would you change?" "I'd leave out classes," he replied._

[https://www.infoworld.com/article/2073649/why-extends-is- evi...](https://www.infoworld.com/article/2073649/why-extends-is-evil.html)

</comment><comment><USER34> Possibly unpopular opinion: Java's biggest mistake, by far, was annotations that define behavior _at runtime_.

So now we have consultingware like Spring where if something isn't working, it could because you missed an annotation somewhere, or put the right annotation in the wrong place. Which annotation? Where? Maybe you'll find out a week from now that you made a mistake, when a customer finds a bug in production.

This took all of the compile-time checking goodness that you got from Java and threw it in the garbage. Now you either have to call an expensive consultancy, read books/manuals about your gigantic framework (fun!), go on forums, etc. You can't just use your coding skills.

I still often use Java for my side projects because I love it without runtime annotations, but thank god for the rise of Golang. I'd rather deliver pizza than go back to the misery that is annotation-driven development in Java.

<comment><USER35> The alternative is heaps of XML or JSON configuration, detached from the code where it's used. Consider that if you wanted to inject a bean in Spring XML it requires creating a bean definition that in turn defines all the beans injected into it, which in turn require their own bean definitions, etc. Then you have to declare exactly which field/method the bean is injected into. If you were developing software in the pre-annotations day you'd understand how much that sucks. The annotation approach is much better in comparison.

<comment><USER36> > inject

I see the problem.

The whole point of spring XML was so you didn't have to "write code" to wire things up. Now we're using annotations to replace XML - we're writing code so we don't have to write code. It makes no fucking sense.

Annotation injections are a completely ridiculous turn of events.

<comment><USER35> > Now we're using annotations to replace XML - we're writing code so we don't > have to write code. It makes no fucking sense.

It does though. Turns out that writing XML configuration means you don't get to take advantage of the context associated with an annotation. I.e., if I put @Inject on method something(X value) in class A, all the context of what type to inject and where comes along for the ride. In XML I have to explicitly specify every single bit of context, and oh yeah, if I rename "A", "X", or "something" I better fix that in the XML or my program will blow up. Not a good look for a programming language that already gets grief about being overly verbose! Annotations just flat out make the configuration part of the equation easier.

<comment><USER37> > I have to explicitly specify every single bit of context,

You still are doing that, just in a less clear way and a less debuggable way. Most other languages get along without meta-languages (there are some frameworks that are spring-like) because being explicit is better than being implicit.

<comment><USER35> > You still are doing that, just in a less clear way and a less debuggable > way.

That's debatable to a degree. If I put @Inject on a field it's pretty clear what's going on just from a quick glance of the source code. By contrast, I don't know injection of some field happened _unless_ I take a gander at the XML config. And the debuggability of both approaches is the same, the injection manager is doing the same magic under the covers, only the configuration is different.

</comment></comment></comment></comment></comment></comment><comment><USER38> On a slight tangent, I'd rather have _only_ checked exceptions, so I know exactly what might throw where. Instead, I have to rely on potentially outdated Javadoc and debugging runtime exceptions in production to find them.

<comment><USER39> I wish that handling/rethrowing wasn't required, but that at dev-time I could just ask, hey, what's every kind of exception that could be thrown out of this expression & then decide which ones I wanted to handle at this level, if any.

<comment><USER40> You can ... ?

Handle some, declare the method throws the others?

<comment><USER39> I don't want to have to write the declares part. I don't want my callers to have to do so, either. I want the nice list of unhandled exceptions the java compiler gives you, but I don't want to have to do anything about it if I'm cool with those exceptions being tossed up a level.

Kinda like if everything was a RuntimeException, but I had a way to figure out what are all the subclasses of RTE that this expression could produce.

Consider how Swift does exceptions. You mark methods as throwing methods, but you don't say what kinds of exceptions can be thrown. If you call a throwing method, you have to write a catch, but in order to figure out what kinds of different things can be thrown, I have to rely on documentation or on examining the source. AFAIK, there's no way to figure out all the different types of exceptions that can be thrown.

I want something in the middle. I want the conciseness of swift, but the info provided by java while I'm writing. I'm no language designer, so I don't even know if that's possible, but it's the kind of pony I want.

<comment><USER40> That Swift way sounds terrible for me.

I do want to know what the error-path contract is, and I do want it enforced that I deal with them. I've seen too much crap in my time that just assumes the happy path, when error handling and recovery are just as important, IMHO

</comment></comment></comment></comment></comment><comment><USER41> If checked exceptions overall are Java's biggest mistake, then the InterruptedException implementation in particular is the second.

It conflates thread management with exception handling in a way that's difficult to understand and implement correctly. The relationship between InterruptedException and the Thread.isInterrupted() method is a particular pain point for coders.

<comment><USER42> What, in your opinion, would be a better mechanism for interrupting threads in Java (aside from just making it an unchecked exception)?

Something like Erlang, where any process will just die upon being sent the exit message, whether it's blocked on IO or receive or busy in the CPU, would definitely be simpler and easier to reason about. But that capability carries a runtime cost.

Go's mechanism is also arguably simpler, in which goroutines are not first class objects and if you want to be able to interrupt one then you have to write ad hoc logic using a channel that you provide specifically for the purpose. But in 99.9% of cases, I think Java's more complicated mechanism with first class threads is more convenient.

I would make it an unchecked exception, though. And I wish the old java.io.Socket operations and similar methods would throw InterruptedException.

<comment><USER41> This is a really hard problem. If you use exceptions at any level they have to be generated consistently, or the solution will be what we have now.

Because that's the other thing--you can't guarantee InterruptedException will even be delivered to a thread. An underlying library can just eat it or the thread could be waiting on a socket [1], etc. This kind of behavior the bane of correctness or even getting operations like clean server shutdown to work at all in some cases.

So I think this really needs to be something like CSP that's built into the language in a way that makes the behavior consistent in all cases even if it introduces coding patterns that have other costs. Java _did_ get object locking and data visibility right by building in simple primitives like the synchronized keyword into the language. You can create deadlocks but the behavior is clean enough it's not hard to program around them.

I would also be fine with just dying as long as there is a way to clean up shared data structures. However, that can't be manual because it's just about impossible to ensure that such cleanups are correct. Databases use transactions to get around that problem.

[1] [https://stackoverflow.com/questions/1024482/stop- interrupt-t...](https://stackoverflow.com/questions/1024482/stop-interrupt- threads-blocked-on-waiting-input-from-socket)

</comment></comment></comment><comment><USER43> I don't think the whole concept of checked exceptions isn't a mistake, although the way they're implemented certainly is. In my experience, the problems with them almost always stem from one of two issues:

1\. Built-in exceptions that are checked but should be unchecked, IOException being the main offender (I don't mean things like FileNotFoundException; I mean the kind you can get if the OS returns -EIO)

2\. Lack of exception polymorphism, preventing you from doing things like l.stream().filter(SomeClass::somePredicateThatMayThrow), even if the function that you're doing it from can throw the same exception that the predicate can

I think checked exceptions would be great and nobody would hate them if those two problems were fixed.

</comment><comment><USER44> This is still one of the pieces written on error handling. [http://joeduffyblog.com/2016/02/07/the-error- model/](http://joeduffyblog.com/2016/02/07/the-error-model/)

</comment><comment><USER45> I sorely miss them in .NET, specially with libraries without any kind of documentation regarding the errors that they throw.

Also checked exception haters always overlook the fact that CLU, Modula-3 and C++ did it first.

<comment><USER46> If anything, I think _un_ checked exceptions were the bigger mistake in Java.

Checked exceptions are pretty much isomorphic to result-types that are oh so fashionable these days (see also Rust), unchecked exceptions on the other hand are completely invisible and unpredictable crazyness.

<comment><USER47> `OutOfMemoryError` is the root of unchecked exceptions, you can't put it everywhere because then it might as well be nowhere.

Rust improves on this by using a different syntax for unchecked exceptions (`panic!` vs `Result`) which provides the benefit of discouraging unchecked without preventing it.

<comment><USER48> Aren't panics() in Rust unrecoverable in release builds?

Except for this minor point, I agree - you can't really make a managed memory system without resorting to unchecked exceptions. Array index out of bounds is another good example of an almost unavoidable exception that would only pollute the code if it had to be checked everywhere (as is Null pointer exception, but that of course could be mitigated by not having nulls in the language).

<comment><USER25> I don't believe so, no.

You _can_ set panics to automatically abort, though. But that's opt-in.

The real point is that panics are absolutely unchecked exceptions, but it's really awkward to catch them and the standard library and entire Rust ecosystem has a good, solid, culture around returning Results whenever reasonable.

The problem with Java is that a bunch of people have no idea what they are "supposed" to do with the unhappy path parts of their programs.

<comment><USER48> Well, as long as the option of disabling panic handling exists, and if it is somewhat widely used in real applications, library writers can't rely on panics as an error-handling mechanism, so generally they have to treat it as if panics can abort the program.

I think the problem of deciding what to do on the unhappy path is often very difficult, a lot of the time much harder than the actual happy path. This is true regardless of the error reporting/bubbling mechanism.

</comment></comment></comment></comment></comment></comment><comment><USER49> I'm a relative newcomer to Java, and, being a newcomer, I have put some effort into exploring as many corners of the language as I can. One that's proven to be a particular puzzle is checked exceptions. But I think I finally understand them now.

I quickly found that checked exceptions just do not play nice with any sort of functional-style programming, like the article describes. But the problem goes so much deeper than that. Checked exceptions are also, as far as I can tell, incompatible with an object-oriented programming style. More or less for the same reason that they interact poorly with FP. The fundamental problem is that checked exceptions don't really play nice with polymorphism or higher-order programming of any type.

Which takes us to the crux of how I understand them now: Checked exceptions may not go well with FP and OOP, but they make all the sense in the world if you're doing procedural programming. There, you're not trying to create deeply nested abstractions, and you're not messing around (much) with polymorphism tricks. The code's very lexically organized, with little in the way of dependency injection or higher-order programming. When you're programming procedurally, it's fine to be exposed to the implementation details of stuff further down on the call graph, because you're the one who put it there in the first place.

And that, in turn, means that checked exceptions are not really a mistake. They're just a piece of evolutionary history. Because, early on, Java wasn't _really_ an object-oriented language. It was a deeply procedural language with some object-oriented features. It arguably still is, it's just that there's been a big cultural shift toward trying to take a more object-oriented approach since Java 5 came along and made it more practical to do so.

<comment><USER33> I agree with the part of your post where you show that checked exceptions are bad, but IMO Java has been OO from the start. And, if by procedural code you mean code that has zero abstractions, then, yes checked exceptions aren't a problem there because their big problem is you can't abstract over them. However, I find this statement more to be an obvious tautology than a statement that checked exceptions are really useful in any situation.

<comment><USER49> My bias there is that I'm one of those Alan Kay worshipping hard-liners who thinks there's a lot more to object-oriented programming than simply using objects. Similar to how there's more to functional programming than using first-class procedures.

So yeah, it's true, Java has classes. But its culture and idioms and standard libraries and even some language features (checked exceptions, for example) are forever pushing developers toward procedural idioms. Less so now, perhaps, but intensely so in the 1990s.

<comment><USER33> IIRC, Alan Kay says OO is message passing, encapsulation, and extreme late binding. In java:

* message passing is virtual method invocation

* encapsulation is through public vs private members

* late binding is through the JVM dynamic linking system.

While Alan Kay may have had something much more flexible like Smalltalk in mind, I believe the Java OO system meets the spirit of OO well enough and makes certain tradeoffs for good reasons.

<comment><USER49> Alan Kay was also fairly specific about what he meant by encapsulation, and it's not just making things private. For example, he wrote, "Doing encapsulation right is a commitment not just to abstraction of state, but to eliminate state oriented metaphors from programming." And, later in the same paper, "Human programmers aren't Turing machines—and the less their programming systems require Turing machine techniques the better."

Java's programming culture tends to favor a shallower approach to OOP that cleaves very closely to the fiddly, imperative, state manipulation-oriented approach that is emblematic of procedural programming.

A great example of this is Java 8's streams API. There's absolutely no way to evaluate a stream without introducing a state change that will alter its behavior. Which means that, unlike for almost any other comparable API in another language, you can't safely pass around and share instances of Stream for fear that someone might break it on you. It's the shallowest possible interpretation of the abstraction in question, and making it that way was a deliberate decision that motivated by the tacit understanding that Java programmers have a fundamentally procedural way of thinking about the world, and would be confused by something that was truly declarative. The only other language I'm familiar with that takes the same approach is another popular "procedural programming with objects" language, Python.

This isn't to say that people _can 't_ do principled object-oriented programming in Java. Just that few people do. In part because, if you try, you'll end up constantly picking fights with the JDK. Not entirely unlike how you _can_ do principled functional programming in Java, but it's an uphill struggle.

<comment><USER33> That statement is neat but it looks to have little to do with programming and more to do with programming style. What about Smalltalk, the language, for instance, helps you "eliminate state oriented metaphors" any better than any other programming language?

</comment></comment></comment></comment></comment></comment><comment><USER38> While we're talking about terrible decisions, can you guess what the following code will print?

      String s = null;
      switch (s) {
          default:
              System.out.println("Hey");
      }

Hint: it will throw NullPointerException.

<comment><USER50> I'm confused why you'd want it to do anything else. Perhaps you could give a more realistic example to motivate the argument for why the behaviour is wrong or inconvenient?

<comment><USER22> It's inconvenient because null could be considered a case

      switch(s) {
        case null: return false;
        case "y": return true;
        default: return false;
      }

The broader issue is that Java handles null inconveniently.

1) Every object can be null, switch requires the argument to be non-null, and the type system doesn't warn you when NPE are possible. A type system which handles nullability could fail to compile if 's' is nullable. Kotlin does this, and it let's you opt-in to the NPE with some convenient syntax:

      switch(s!!)

2) It's inconvenient to handle null as a value. To properly handle the null case without throwing, you need to do one the following:

      if(s == null) { ... }
      else switch(s) { ... }

      switch(s == null ? "some-default" : s)

The first way can be made more convenient if you change switch to work on nullable values. The second way is inconvenient, so people generally skip it. If you want switch to only work on non-null values, there're more convenient syntaxes to handle null, such as the 'elvis operator':

      switch(s ?: "some-default")

<comment><USER51> You could also use Optional, like

Optional.ofNullable(s).map(i -> {switch (i) {...}}).orElse()

</comment></comment></comment></comment><comment><USER52> Mistake maybe but I disagree on the 'biggest' part.

For me type erasure is a bigger issue. I get that it was done for backwards compatibility but the drawbacks imposed by that decision seem to only grow as more time passes and more new compromises have to be made.

<comment><USER42> What, in your opinion, is the biggest drawback of type erasure?

<comment><USER53> Some things that came to my mind:

\- List<T> doesn't "just work" with non-reference types. It needs boxing that increases memory usage and introduces stuff like ints being null.

\- We need special functional interfaces for non-reference types for that reason (e.g. IntConsumer).

\- This also affects Stream<T>, so we need IntStream etc.

\- A method must have a parameter of that generic type (or it has to belong to a class that has this generic type). It otherwise becomes indistinguishable during rumtime. For example, a method like ImmutableList.CreateBuilder<T>() is not possible in Java (that example is from C#'s collection types).

Type erasure moslty comes into play when looking at non-reference types. For reference types, it seems to work pretty good (although it's weird that Map<String, String> will have the same runtime type as Map<Object, Object>). The last point I mentioned is not good, but no deal breaker. If generics would be like in .NET, we wouldn't have any of these restrictions.

With type erasure, we ironically have to write more java code while not being able to express stuff in an abstract manner (Stream<T> is incompatible with IntStream).

<comment><USER54> Thankfully, C# team made the right call and used reification.

</comment></comment></comment></comment><comment><USER55> I just want to throw a plug for the concept of Railway Oriented Programming. It can be laid on top of almost any functional-ish language that can implement some sort of Result(Ok,Err) return type. And to the OP's point, you can catch exceptions where they occur and `return Result(Err(details))`.

We applied ROP with great success at a fintech where we wanted to clean up a block of business logic with many failure paths. Instead of a forest of nested conditionals or try/catch mess, there was a very simple happy path with clear handling for all the errors.

Here's a good start. Ignore the language details, the concept is universal. [https://fsharpforfunandprofit.com/rop/](https://fsharpforfunandprofit.com/rop/)

</comment><comment><USER56> I've been using java since Pre-1.0 and professionally since 1999 and I don't see checked exceptions as being particularly high up the list of java issues.

Even with all the functional stuff they almost never seem to really create a major issue.

My biggest issue with Java is just the way they've caved and constantly added new stuff that is always grafted on so it's never quite as good as a language that focuses on that programming paradigm from the start.

But none of the problems in the language compare to the scale & scope of the problems caused by Java's default developer & architect culture. The culture is terrible... everything gets overcomplicated, overabstracted, etc. and you've got charismatic charlatans convincing wide swaths of developers to misuse and abuse language features in ways that have made a lot of people hate the language and have produced a lot of buggy and hyper inefficient code.

Java itself doesn't have to be bloated, slow, buggy, and a massive memory hog. But the java developer community has continually made decisions to structure their java software in a way that makes that the default condition of Java systems. The way the Java language constantly gets new giant features grafted on plays into this.. everyone jumps on the latest language addition and misuses it for a few years before they come to understand it. By the time it's understood there's something new to move onto and abuse.

Java became everything about C++ it was originally supposed to simplify.

<comment><USER29> The reason for the complexification is the culture of unit testing, and in particular cargo culting that idea to mean every class needs a corresponding test class, every method needs at least one corresponding test method, etc.

In order to tests classes in isolation like this, all dependencies must be injected, so they can be stubbed or mocked.

Because there's no universally available IoC framework or baked-in functionality, everyone takes the library approach to DI, which means factories of various levels of abstraction, and an excess of parameters.

But in practice most production Java systems do run with an IoC container, which in turn makes more fun things possible - AOP, interceptors, automatic transactions, all manner of magic.

(There's no doubt that checked exceptions were a mistake, to my mind, but the mistake is being repeated in Rust, so I guess that lesson hasn't been learned. But perhaps all checked exceptions needs is a better type system to manipulate the error types through the control flow graph. We'll see.)

<comment><USER57> > In order to tests classes in isolation like this, all dependencies must be > injected, so they can be stubbed or mocked.

This really boils down to which school of testing you follow. London (Mockist) vs Detroit/Chicago (Classicist). [0] is a good article on the different views of testing. Made me think more about it.

I find that using fewer mocks, and unit tests that integrate many classes (vs one set of tests for each class) makes Java programming more fun- but it is very much a Detroit school way. And that's okay, but it's good to really think about the differences.

[0][https://medium.com/@adrianbooth/test-driven-development- wars...](https://medium.com/@adrianbooth/test-driven-development-wars-detroit- vs-london-classicist-vs-mockist-9956c78ae95f)

<comment><USER58> Good article/comment. Thanks!

</comment></comment></comment></comment><comment><USER59> There are two kinds of exceptions: (1) those that can (and should) be handled in a meaningful way, and (2) those there's no way to handle and you should just crash.

A big part of the reason people hate checked exceptions is that actually doing #1 correctly is really damn hard. It's a whole separate dimension of complexity that your design needs to tackle.

A compiler that checks exceptions forces you to do it. Abruptly, if you're new to the language. It flips the floodlights on at full brightness and makes you see the full scope of the problem. It's tempting to shoot the messenger.

</comment><comment><USER60> The biggest mistakes in Java are checked exceptions, NullPointerException, and primitive types. But which one of these is the _worst_ mistake really depends on your perspective, and the mood of the day.

<comment><USER54> \- primitive types \+ not having value types

FTFY

</comment></comment><comment><USER61> Rust has a system equivalent to checked exceptions.

However Rust, unlike Java, has a great macro system and can thus easily generate higher level exceptions wrapping the lower level ones.

<comment><USER21> Rust's macro system is not what makes its "system equivalent to checked exceptions" bearable.

That the language provides tools to operate on both results themselves and their content (in part because results are reified and thus normal values of the language, and in part because specific tooling like `?`) is what does that.

Also that there is no issue of misclassification as in Java, because everything is a result and that's that.

</comment></comment><comment><USER62> In my eyes, Java's biggest mistake is that the byte type is signed instead of unsigned. Masking a signed byte with (b & 0xFF) causes so much needless pain, and I have never wanted to use a signed byte. On the other hand, I appreciate that Java doesn't have unsigned versions of every integer type; that simplifies things a lot. As for checked exceptions, I'm still undecided on whether they're a good or bad thing.

</comment><comment><USER63> I liked checked exceptions. It makes you aware of what exceptions that might happen. Makes you think about how to handle it.

</comment><comment><USER36> The biggest problem with checked exceptions is that the application writer decides what is a recoverable error. Not the library designer. I could easily imagine a program where SQLException is a recoverable error. But I don't write those types of programs.

<comment><USER64> well the problem is that SQLException is not a good exception at all. it actually includes the following errors:

        - database connection closed
        - SQLTimeoutException (o.O)
        - protocol exceptions like duplicated key
        - query exceptions

the problem is that some of them are recoverable but usually it's more of an hassle and duplicated key exceptions are easier to handle in app code via upsert, etc.

so basically the problems are library designer errors and not application writer errors.

checked excpetions should only be exceptions that a developer COULD handle and not ones that he can't

in C# the library designers usually create a "Result" object that has a boolean of succeded or status of enum instead of using exceptions for failures. i.e. most i/o errors are not recoverable, thus c# does not enforce you to recover from them.

<comment><USER65> Yeah it's reasonably common for people to try and salvage checked exceptions by saying people are doing them wrong but at some point you realize the best you're doing is trying to put lipstick on a pig.

Here's a bigger problem: checked exceptions pollute your API and expose implementation details. Consider an API that stores and retrieves objects. A particular implementation does so by writing them to a database via JDBC so you get SQLExceptions. You have two basic approaches:

1\. Include SQLException in your function signatures so the caller can deal with it. This exposes the implementation detail; or

2\. You can hide it by transforming that checked exception into something specified for your API. At this point, what benefit have you gained from SQLException being a checked exception? You're hiding that detail.

For (1), you're baking checked exceptions into your function signatures such that it can be really difficult to change later on.

If you sit down and think about the practicalities the argued upsides of checked exceptions are essentially nonexistent and unchecked exceptions are actually strictly superior.

Here's another pattern that happens with checked exceptions in Java:

        try {
          doSomeSQL();
        } catch (SQLException e) {
          // do nothing
        }

You will see people do this all the time because they don't want to deal with the checked exceptions. A better catch-clause is:

        throw new RuntimeException(e);

You can argue people shouldn't do the first and they shouldn't but unchecked exceptions will simply bubble up unless you deliberately swallow it. That's a way better default. Defaults matter.

<comment><USER66> > _checked exceptions pollute your API and expose implementation details_

Exceptions aren't an implementation detail. They're part of the API contract. Checked exceptions make this explicit, but people don't like that because error handling is hard and pretending that errors don't happen is easy.

<comment><USER64> I argue against that. because the problem is not that error handling is hard, the problem is that it is mostly unnecessary. Basically if you would write a hello world that writes directly to STDOUT you would need to handle IOException, guess what? it's basically useless to handle any kind of IOException in that case, because guess what? if your i/o device for output to display is broken you can only let your program crash. and that is the most common case how most exceptions are handled. and thats excalty where the k8s hype is about.

fail fast, start from scratch. you can't handle a network error in your application, but you can basically kill everything that lost network access to your database and recreate it where database access is still possible. but you don't need to do that in your application, your infrastructure should handle these and thats why most checked exceptions in the java stdlib are basically stupid. 90% of the stuff reuses exceptions for ease of use but 90% of the stuff should be runtimeexception and 90% of them should split them up, between stuff that I COULD recover from and from stuff that I can't (i.e. SSLException should be split into validation of certificate exceptions and protocol violations!!! that mostly can't be handled without reconfiguring the JVM!!!! I mean there is a SSLProtocolException but it's basically useless since it reports a totally different thing..)

</comment></comment></comment></comment></comment><comment><USER67> The sad bit about checked exceptions is that everyone compares any sort of error tracking to them and immediately dismisses many useful ideas

Java's checked exceptions got the worst possible combination of error tracking. Its optional, so you don't even get to see if a function throws (kind of like the billion dollar null mistake) and its based on classes, which means a lot of irrelevant names leaking throughout the codebase.

Like with nulls, the main value is being able to claim that a function doesn't ever throw, at all. Apple's Swift got this just right.

A simpler system of "throws / doesn't throw" and with optionally polymorphic variants / unions to complement it would go much further.

</comment><comment><USER68> The biggest mistake of C# is not having checked exceptions. Your carefully written program can crash because someone modified a dependency to throw a new exception. So the only way to make your program resilient against such changes is to catch the base Exception class, which everyone agrees is wrong (because of "swallowed" exceptions). In Java the compiler alerts you if someone modifies a dependency to throw a new exception, which is good.

See long discussion here: [https://email@example.com...](https://email@example.com)

<comment><USER54> Arguably, a careless library developer can break your code in infinite different ways than changing the exception type, even in Java.

I'll get one in a million chance of careless library developer randomly changing exception types over writing `throws` and `try/catch` statements a million times even when I don't need to handle any exceptions at all.

</comment></comment><comment><USER69> I've found checked exceptions pretty useful. I can pass context-specific details to the exception and encapsulate the message formatting to the exception itself (helps if I'm throwing that in multiple places). They also allow me to decide the http return code based on the exception. E.g. using Spring Boot's controller advise, I can map a group of exceptions to be user errors (say, bad request) and another group to be service errors (say, internal server error) etc and don't have to worry about where the exception is being thrown from - it'll return all the details with correct return code to the user.

</comment><comment><USER70> Having used Java somewhat, the biggest pain points I encountered with checked exceptions was their incompatibility with highly generic code (aka streams). What if all library functions taking lambdas (e.g. map, filter) all took throwing functions as parameters (i.e. have an extra generic X argument for the exception type, like R apply(T arg) throws X) and simply rethrew those exceptions, AND have the exceptionless functions (R apply(T arg)) be a subtype of the throwing version so they are compatible? I haven't touched java in a while so I may have forgotten a thing or 2 about its type system

</comment><comment><USER71> I would prefer there were just a semantic way to find out what exceptions a method might throw. I develop a lot of Java and often end up just rethrowing a checked exception as RuntimeException or AssertionError.

A long time ago, I developed quite a lot of code in Ada83. Our team found having to use documentation to express what exceptions might be thrown led to many errors. I was pleased when Java came around that this was expressed directly in the function declaration.

But then it became clear that it lead to a lot of boilerplate.

I would like the throws keyword to just be an indication of what might be thrown and not require that I catch it.

</comment><comment><USER23> I don't mind Java checked exceptions but of the languages in this style I think I prefer C#'s Task type. It combines a promise with a simple IsFaulted boolean and a way to rethrow the caught exception at your discretion (or it will throw if you accidentally access the result getter).

You can use catch block style with typed exception handling or simple boolean checks depending on the situation and what you prefer.

</comment><comment><USER72> Java has checked exceptions, unchecked exceptions, and errors.

Some checked exceptions, such as InterruptedException, should really be something else. I've very rarely seen this exception handled properly by anyone. Often, a general catch Exception will also catch this, and while the code will work just fine in most circumstances, random threads will not go away when they should.

It's a mess.

</comment><comment><USER73> Java's biggest mistake was not including lambdas and generics from the very beginning. Checked exceptions are a feature because they force you to think about how you will handle exceptions: usually one of die, try again, or try something else. Forcing the programmer to make these decisions explicitly is a good thing.

<comment><USER54> C# had also adopted lambdas and generics post first release, but made all the right decisions for transition so type system isn't a mess.

</comment></comment><comment><USER74> If the exceptions thrown by your code aren't part of the interface, then pretty much nothing is. That means strong typing is actually Java's biggest mistake.

This isn't to say that checked exceptions are always used well. (What exactly am I supposed to do about an exception from .close()?)

</comment><comment><USER51> Most codebases use lombok, you can use @SneakyThrows or @SneakyThrows(SpecificException.class) - [https://projectlombok.org/features/SneakyThrows](https://projectlombok.org/features/SneakyThrows)

</comment><comment><USER33> I'm surprised how controversial this is; checked exceptions are a mistake. There is a reason C#, Go Swift, Rust, Scala, etc. don't have them, and it's not because these language authors don't know what they are doing.

Checked exceptions have all the disadvantages of monads:

* Checked exceptions don't _compose_ with each other. You have to create manual witnesses of composition (methods throwing multiple exception types, or wrapping exceptions into new exceptions like a monad transformer)

* Checked exceptions infect the type system, having to be copied everywhere.

However, they have none of the advantages of monads, and more disadvantages besides. Java the language does not provide any facilities for abstracting over checked exceptions, and they interact terribly with any design involving higher order functions or any other higher-level abstraction.

It's time for the java community to admit they got this one wrong and move on.

<comment><USER40> > Java the language does not provide any facilities for abstracting over > checked exceptions

Can you explain what you mean by this?

<comment><USER33> I can't write a method like this:

public <T> higherOrderFunction(Function<T> f) throws whatever f throws { }

I can write a method that takes in a function object that throws zero checked exceptions. I can write a method that takes in a function that throws exactly one type of checked exception. I can write a method that takes in a function object that can throw two types of checked exceptions. And so on. But this involves lots of copy-pasting, which is the opposite of abstracting.

Checked exceptions are not first-class citizens in the language (see [https://en.wikipedia.org/wiki/First- class_citizen](https://en.wikipedia.org/wiki/First-class_citizen)). Unlike return values, I can't, for instance, in the general case assign the possible checked exception thrown by a method to a variable without losing type information. To do so would require sum types, a feature which most popular languages don't have.

On the other hand, if I create a class like IO<T>, which represents a possible return value of T or an IOException, then that is first class in the language and I can do anything with it that I can do with any other first-class value in the language.

<comment><USER40> So you effectively want -

class ThrowingFunction<T, R>{ public T execute() throws R; }

public <T, R> higherOrderFunction(ThrowingFunction<T,R> f) throws R { }

Honestly I have no idea if such a construct is possible. You can write a method that throws a superclass of exceptions.

At this point though I'm going to say I also don't see the utility. By the time we're getting so abstract we're also getting into code that can be quite hard to reason about and debug.

Exceptions are first class in java AFAICT, they're just objects. You can store anything in them and pass them around freely.

</comment></comment></comment></comment><comment><USER75> I write a lot of Java, and like checked exceptions. The problem is rather the opposite, basically all of the concrete exception classes that you might think to use (e.g. IllegalArgumentException) are unchecked!

</comment><comment><USER76> Sure and they are a big, big mistake, but biggest? I can name bigger ones. Default virtual is quite the whopper, for example.

<comment><USER77> Looking it up, "virtual" seems to mean "capable of being overridden by a subclass". Rather than being a whopper, wouldn't that be the natural thing for a pure-ish OOP language?

<comment><USER78> If you know that a method isn't virtual, calling that method is just a function call with an extra argument for 'this'. If it's virtual, you have to look it up in a vtable, probably dereferencing two pointers in the process and making it harder on your instruction fetcher.

Java makes a lot of common classes final (e.g. String and Optional) so that it can avoid this. As I understand it, it's also got a lot of pixie dust to predict this some of the time, but then you can't rely on it.

<comment><USER79> When the JIT was finally smart enough to handle lookups better, they didn't change the types.

Final classes encourage the creation of utility classes, which can often become a problem.

</comment></comment></comment></comment><comment><USER80> I also see people saying they miss checked exception because developers always forget to check the returned error code...

</comment><comment><USER81> Checked exceptions are hardly Java's biggest mistake.

</comment><comment><USER82> It's easy to see that checked exceptions are bad... no other language tried to copy the idea. A worthy experiment, but that's all. What else did not get copied? Classloaders.

<comment><USER25> Actually, PHP has checked exceptions exactly like Java

<comment><USER82> Well, that I did not know. But I'll take it as the exception that proves the rule if only one language copied it.

<comment><USER25> It's certainly not an endorsement of checked exceptions. Just an FYI. And, further, PHP is basically just copying every feature they can from Java for the last several years.

</comment></comment></comment></comment><comment><USER83> My biggest complaint with Java is Generics. I am not against Generics, I don't like the way they were implmented in Java and they copy/pasted the same shit to C#.</comment>


Gizmodo Really Likes Patent Trolls - <AUTHOR> http://gizmodo.com/5621899/why-we-need-more-inventions-lots-more-inventions Really not understanding why the author is giving so much free publicity to a well known patent troll. See here: http://www.techdirt.com/articles/20100217/1853298215.shtml <comment><AUTHOR> Here are three more very recent articles promoting IV: <http://gizmodo.com/5621869/why-ideas-are-expensive> [http://gizmodo.com/5621679/how-intellectual-ventures- wants-t...](http://gizmodo.com/5621679/how-intellectual-ventures-wants-to- reinvent-invention) <http://gizmodo.com/5621607/iv-gallery/gallery/>

I am at a loss why this would be something Gizmodo would fall for and publicize. Didn't they do a google search?

<comment><USER2> Aren't they Gawker's? fact checking was never a priority there.

<comment><AUTHOR> True but damn, why so many articles in such a short period of time by the same author. It makes me very skeptical of anything else they put out.</comment></comment></comment>


Nokia-Microsoft Deal Gets Signed - <AUTHOR> http://techcrunch.com/2011/04/21/nokia-microsoft-deal-gets-signed-volume-shipments-on-schedule/

<comment><USER2> Let me see if I have this right: the CEO of Nokia very publicly declares that he is going to bet the company on WP7 weeks before finalizing a deal for WP7.

Didn't the very public declaration, which IIRC caused _resignations_ by engineers working on Symbian and Meego, radically weaken Nokia's negotiating position?

I must be missing something because it is unlikely that the leadership of a major corporation would be that unskillful at negotiation.

<comment><USER3> It has been suggested that Elop was installed at Nokia specifically to act in Microsoft's best interest. Indeed, his actions make sense when so viewed.

Interestingly, this may be his specialty: check out his movements preceding the sale of Macromedia to Adobe.

<comment><USER4> Can you unpack 'was installed'? Microsoft doesn't have the ability to appoint Nokia's CEO.

<comment><USER3> Of course they wouldn't have the ability to appoint at will, but they certainly could install opportunistically. You start by spotting someone who manages their career in a way that indicates useful skills and mindset:

[http://www.siliconbeat.com/2008/01/11/microsoft-beware- steph...](http://www.siliconbeat.com/2008/01/11/microsoft-beware-stephen-elop- is-a-flight-risk/)

...then you make them a high-valued member of your senior leadership team...

<http://www.crunchbase.com/person/stephen-elop>

...then when opportunity strikes and Nokia tries to buy him away you set up an under-the-table quid-pro-quo deal that would, one presumes, dwarf the $6m signing bonus Nokia gave him:

[http://siliconangle.com/blog/2011/03/11/stephen-elop-of- noki...](http://siliconangle.com/blog/2011/03/11/stephen-elop-of-nokia- receives-6-million-signing-bonus/)

Sure, it's just conjecture, but it's not implausible.

<comment><USER4> You haven't answered my question _at all_. I'm asking how MSFT can "install" someone at Nokia. All you've said is that Elop was a good employee who got promoted, and then Nokia came and tried to hire him. That's not MSFT "installing" anyone.

The far simpler explanation is that if Elop is going to make a big bet with Nokia, he feels safer doing it with MSFT (who need Nokia, and where he knows people) than Google (who don't, and where he doesn't).

<comment><USER3> I'm sorry. The only question that I see is to unpack "install", which I take as a figurative expression meaning to analyze something into its component elements. I broke down everything that I meant to imply by the word, so you'll have to ask a different question.

 _Edit to reply below: your probability analysis ignores Elop's improbable behavior as described by hollerith above. And, again, this is not my explanation (this conjecture was all over threads discussing the deal the day it was announced). I'm not even saying that I buy into it, although I do have to acknowledge that people involved with deals in the billions of dollars are seldom strangers to opportunism._

<comment><USER5> I think a more likely explanation is that the causality is in the other direction: the Nokia board was already leaning toward making a deal with Microsoft before they hired Elop, and he was hired with that in mind.

</comment></comment></comment></comment></comment></comment></comment><comment><USER6> Am I the only one that sees this as a good thing?

Nokia gets an reasonably well made OS to replace its own, widely criticized, OS. Nokia instantly becomes the one of (if not _the_ ) largest WP7 vendor, thus giving it way more negotiating power than if they were to adopt Android.

Microsoft gets the largest handset maker to adopt an OS that is struggling to gain traction, instantly upping their credibility in the market.

The rest of us get a legitimate third player in a smartphone market dominated by iOS and Android.

<comment><USER7> no, you are not the only one.

Managed correctly I don't see how this won't benefit each party. Nokia makes good phones. The software, less good. Microsoft has tonnes of experience creating user interfaces that are user friendly.

I'm a long time linux guy who uses a 6 year old Samsung dumb phone, but I bought NOK and MSFT after the initial announcement. No guarantees in this world, but I think it was a good bet.

</comment></comment><comment><USER8> And here marks the beginning of Nokia's transformation to an OEM...

</comment><comment><USER9> This deal sounds very similar to MS-Yahoo deal. Abandon your existing technology, rely on competitors tech and expect growth.

We have seen how MS-Yahoo deal played out this week. It won't be long before Nokia realized what they got into. By then, it'll be too late.

<comment><USER10> It looks that way, which is pretty sad. I'm typing this on my beloved N900, which I found far more usable and open than Android (which I kicked when it wouldn't stop screaming "CLOUD! CLOUD!" at me, and Eric Schmidt kept coming into my house at night to smell my hair).

Seriously, though, there are only two real competitors, Apple and Google, in the smartphone market, which is unfortunate for everyone. Windows phones have been floundering, WebOS seems to have lost traction, and Blackberries are...Blackberry who? I hope we're not entering the Dark Ages of Mobile Phones.

<comment><USER11> I've been waiting a long time for the successor to the N900. It's sad it'll never happen, and that there's nothing similar on the horizon (especially with Maemo/Moblin/MeeGo floundering).

</comment></comment></comment><comment><USER12> Note, other MS partner deals that work oh so well:

MS-Yahoo..the current revenue numbers indicate that with MS's help Yahoo will reach a floor of below $200 million within one year from now from a high of several yeas back of $500 million.

How many restarts for winCE now? Is it not he 5th code base restart? Gee Nokia should be right at home than :)

<comment><USER13> >How many restarts for winCE now? Is it not he 5th code base restart?

Reference?

<comment><USER5> As far as I know, there hasn't ever been a code base restart for Windows CE (the kernel and infrastructure components). The Pocket PC/Windows Mobile/Windows Phone interface/app platform layer above it has been restarted a couple times, hence the name changes.</comment></comment></comment>


Fear the reaper: characterization and fast detection of card skimmers - <AUTHOR> https://blog.acolyer.org/2018/09/03/fear-the-reaper-characterization-and-fast-detection-of-card-skimmers/ <comment><USER2> Poland solved this problem pretty neat. I don't even remember using my credit card with ATM.

You open your mobile bank app, click BLIK icon and a 6-digit code is generated. You enter the code in ATM and you choose amount to withdraw. You accept the amount on your mobile phone and money comes out.

This is how it looks: [https://www.mbank.pl/indywidualny/uslugi/uslugi/blik/](https://www.mbank.pl/indywidualny/uslugi/uslugi/blik/)

<comment><USER3> That's very clever but honestly, just removing the magnetic strip seems like a really obvious first step. I know for a fact they flag magnetic strip usage on ATMs for credit cards anyway. (Then again, could be some sort of honeypot.)

</comment></comment><comment><USER4> "The measurement card has a carefully etched set of traces in the magnetic stripe, (aligning with each of the three data tracks). When a read head contacts the card it bridges a pair of electrical traces and completes a circuit back to the microcontroller."

This seems to me to be a detective control which relies a bit too heavily on obscurity, obscurity which is now blown. Having knowledge of how this works, ATM skimming gangs who's devices might be found by local authorities with this device can now take the active counter-measure of placing a piece of Kapton tape over the read-head.

<comment><USER5> Or maybe they can monitor the wires on the legitimate read head instead. This was possible on a formerly common fuel dispenser in the USA

</comment></comment><comment><USER6> This is _very_ cool. Basically a 'fake' card that can detect when it passes by more than one 'read' head in the machine.

It should be possible to build this into a credit card sized device that you could just swipe with and have it illuminate a red or green LED when it detects a skimmer.

<comment><AUTHOR> Well, you have a point there. But don't you think the "credit card sized device" will again be used for fraudulent purposes? Maybe to trace EM emissions or something else?

<comment><USER6> Perhaps, but the gist of the article is that you basically won't be able to detect a skimmer most of the time. But their technique does detect skimmers (all the time when they tested it). What I was wondering was if you could carry something in your wallet to easily check for skimmers. A CC sized think PCB with a thin package on it would be idea, and then a paper overlay to create uniform thickness.

<comment><AUTHOR> >> A paper overlay to create uniform thickness

Might I ask what purpose would it serve?

<comment><USER6> Some places have automated rollers that move the card in and out of the machine. I would not want to lose my skimmer detector by having it getting hung up inside the machine.

<comment><AUTHOR> Thanks for explaining your thoughts :)

</comment></comment></comment></comment></comment></comment><comment><USER7> We should really add 2FA to cards. E.g. if I withdraw a large sum or make an unusual transaction prompt for a 2FA code.

For small transactions it makes no sense, but for anything above a user defined limit we should have this option. e.g. I only withdraw more than £50 in unusual circumstances.

<comment><USER8> In EU all banks have to implement 3D Card Secure - when making an online payment over a certain amount, or of an unusual type the vendors website redirects you to your bank's website where you have to authenticate the payment(usually provide an SMS code or answer some security questions).

<comment><USER9> In Finland you get a tiny card filled with single use pin codes. It's pretty secure. Unfortunately, if your card is skimmed, the scammers will just -- for example -- associate it with an Uber account and sell the account. Because non-EU companies don't use 3D-secure there's nothing stopping them. I have tried asking for non 3D-secure transactions to be blocked, (I believe when a vendor doesn't offer it I can always find an alternative) but no such luck. (Obviously you can get the money back, but I'd like to avoid the inconvenience and the fact the scammers get money for nothing.)

<comment><USER10> > In Finland you get a tiny card filled with single use pin codes. It's pretty > secure.

Nordea Bank Finland ceased providing code cards earlier this year. Logging on to online banking even warns that the code card you already have may stop working soon. Everything has moved to the mobile app or, available as a special order for the elderly and luddites, an electronic keypad.

</comment></comment></comment></comment><comment><USER11> Do cards still use magnetic strips? I thought it was all done on the chip nowadays?

<comment><USER12> In the US they generally have both if issued in the last few years, but many places still accept magnetic strips. I don't use an ATM often anymore, maybe once or twice a year at most, but I've yet to see an ATM that only demands the chip instead of forcing you to insert the whole card, so chip-only debit and credit cards can't come soon enough.

Curious if there's an easy way to make my stripe unreadable with my most used credit card, especially for dining where your card can disappear for several minutes at a time.

<comment><USER13> Revolut lets you disable the magnetic strip and other functions (e.g. contactless) of your physical card via the App.

<comment><USER14> As do Monzo, infact the magnetic strip is disabled as default and you can only enable it for 24 hours at a time.

</comment></comment></comment></comment><comment><USER8> I just don't understand why my card even has a magnetic stripe anymore. It's been years since I've seen any terminals that could actually accept it, it's all chip and pin over here. If I could get a card without the strip I'd gladly do so.

<comment><USER15> The United States is still predominantly magstripe. We've had chip-and-no-pin for a few years but many large retailers haven't enabled it, possibly because transactions are so much slower (usually 30-60 seconds) and less reliable.

<comment><USER16> > possibly because transactions are so much slower (usually 30-60 seconds)

I don't know the details of the technological differences in transaction communication between the two, but in the UK chip and pin is noticeably and consistently faster to perform transactions in my experience, often to the the point that it's perceptibly instant... although it has been quite some years since i've used magnetic ones so that's from memory.

I suppose one way to protect yourself if you are never going to use your card in the US, is by destroying the magnetic strip (magnetically).

<comment><USER15> The slow reads are entirely a technical failure by some of the large vendors. Some systems are as fast as you describe and most of the ones which I see being that slow are much faster for NFC, so I'm pretty sure it's just that they were rushed into profuction to meet the deadline imposed by the card vendors.

<comment><USER16> Maybe it's just a difference in how relatively new the technology is to US retailers then, UK shops have had plenty of time to work out the kinks and learn what hardware to avoid.

<comment><USER17> The first generation of Chip&Pin in the UK were garbage too. Slow and often failed to read the chip, resulting in awkwardly cleaning the chip contacts.

Most of the machines were replaced inside of the first year and things have improved substantially since then.

<comment><USER16> Ahh yes I do remember a few instances of that now... I wonder what the introduction of the magnetic strip was like, looks like that technology arrived in 1969, anyone here experience that transition?

</comment></comment></comment></comment></comment></comment></comment><comment><USER18> As an anti tamper measure, the ATM will not just pull in the card and read it; instead, it's movement is somewhat randomised, as to increase the difficulty of obtaining an illicit read. (At least the ATMs in my country are said to usually do that)

As a result, the ATM's read head might pass over the detection spot multiple times.

Maybe you can force the measurement device to move only in one direction, but if I were to design the ATM, it would detect inconsistent, physical card movement.

<comment><USER19> > Maybe you can force the measurement device to move only in one direction, > but if I were to design the ATM, it would detect inconsistent, physical card > movement.

That would be very prone to false positives. Weather variations (temperature, humidity), card types, dirt (grease , dust) and foreign objects (stickers on the card) etc etc would all make the card movement inconsistent.

<comment><USER18> I don't think so. If you don't know how it moves, you can not read meaningful data (if it moves forward/backward). That's the whole point of that counter measure.

If they [the ATMs] do this and can read the card, then they can also check that the measured movement matches what the controller sent to the motor driver. Heck, depending on the driver they could just let it measure back EMF (e.g. some Trinamic stepper drivers can do that).

</comment></comment></comment><comment><USER20> This should be provided by ATM manufacturers along with the ATM, and part of a mandatory daily check before the machine can be used.

</comment><comment> Paul-ish It would be nice if I could clip on a thin piece of plastic/foil to my card to block out the magnetic strip if I know the device I'm inserting it into only needs the chip.

</comment><comment><USER21> I'd love to have a mini version of this that is just the size of a credit card and could fit in my wallet.

</comment><comment><USER22> I live in the US where you essentially have no liability for fraudulent transactions (if you identify them in a reasonable amount of time) - so while it's annoying to have to get a card reissued once every couple of years, it doesn't seem like such a big deal

<comment><USER23> I can't recommend SMS alerts for all transactions highly enough... that way even traveling you know what went through, when, and for what amount.

However, once a year seems optimistic for card replacement, if you use them at a lot of POS (gas stations). I've seen replacements at once a week (every time they filled up) and the gas station attendent doesn't care either.

<comment><USER24> I have this as well, but using email. They automatically sort into a folder and I can go through them later, super convenient.

</comment></comment></comment><comment><USER25> >There's one thing that's fundamental to overlay and deep-insert skimmers – they have to actually read your card data! This requires a read head pressed against the magnetic track on the card with a spring mechanism. Furthermore, the head must be a conductor and in practice seems to always be metallic.

next up: skimmers with "undetectable" read heads (lined with plastic)

I've seen cashiers sandwich cards between pieces of paper to get problematic cards to read, which makes think that while the read head must be metal, it doesn't have to be in contact with the card to work.

</comment><comment><USER25> >... those that fit in the EMV slot (chip reader) and those that wiretap the physical communication line.

What's the point of wiretapping the emv chip? Isn't EMV supposed to be immune to skimming?

<comment><USER26> The full sentence is

> External devices can be attached as card reader overlays, deep-inserts > inside the magnetic stripe slot, those that fit in the EMV slot (chip > reader) and those that wiretap the physical communication line.

I believe the "those that fit into the EMV slot" and "those that wiretap the physical communication line" are two different types.

A skimmer in the EMV slot can still skim the mag-stripe. Wiretapping the communication line is used when the ATM/Payment terminal uses poor security between it and what ever its connected too.

<comment><USER27> Except an insert into the chip reader slot isn't a full insert of the entire card, and so they're not going to get the full mag stripe.

Now, if they don't need the full mag stripe, then you've got a problem. But I don't think that mechanism would work for most skimmers.

<comment><USER26> Some of the card dip style readers do have a full card insert. Examples would be the in shop ATMs that prevent the card from being removed (so they can query the chip).

</comment></comment></comment></comment><comment><USER28> Better than hoping your customers are carrying their own detection device, build such a detection mechanism into the rear of the card slot and have it periodically "sweep" itself.

</comment><comment><USER29> There is a clever solution to this from a bank in Slovakia (Tatrabanka), you can use their mobile banking application to generate a one-time numerical code for the withdrawal. So you can just generate the code and enter it on any ATM that is owned by this bank. You don't need to have the card with you (and you can forward this code to your wife for example). Also 100% of cards in Europe are also protected by PIN, so simple skimmers won't work.

<comment><USER30> PIN does not protect you from skimmers... Everything you need is on the magnetic stripe, PIN is only needed if you use the chip - which an attacker obviously wouldn't.

The whole concept of chip+pin is pretty pathetic considering that the magnetic stripe is still there for backwards compatibility.

And now with wireless cards it is even less secure than a magnetic stripe.

<comment><USER31> I've seen you claim wireless cards are really insecure a few times in this thread. I was wondering about a source, and about the mechanism.

Certainly, using rather basic NFC smart card technology, all but on-line attacks _could_ be eliminated. My question is then, what kind of low- protection protocol do they use in practice to make this so insecure.

Specifically, I am asking about an offline attack that allows an actual spend the bank would accept. I am also only interested in debit cards (because that is what I have) so just reading a CC number from NFC doesn't bother me.

<comment><USER26> My "Party trick" when NFC payments was newish in the UK was using a pair of Nexus S phones in a relay attack.

I would say to a friend "I bet I can buy the next round using your card, if I can you buy the round if not I'll buy the round" Get them to place their wallet with their card in it on the table with one of my phones near the wallet and I would present my other phone to the reader at the bar.

At the time the bar I did it at had public wifi without Wireless Isolation so I could use the bar's wifi as a low latency connection between the two phones but back then the tolerances on the timings would allow you do do it with a decent mobile connection. (At one point you could just get a NexusS custom rom already set up for this replay attack).

It was more of a party trick as you had to have close proximity to the payment card as it was just a relay attack and the banks limited NFC transactions to a max of £20 which the banks would cover (its been bumped upto £30 these days or more if you auth with biometrics like with Apple Pay if the store permits the transaction).

I believe NFC payment terminals these days have tightened up the timings of card reads to make such relay attacks more difficult.

<comment><USER31> Yeah, active attacks are where PIN-less NFC gets really scary. That said, just losing such a card is also scary.

It amazes me how timing makes it possible to detect this kind of stuff.

<comment><USER26> I've never been asked for a pin when using NFC payments (if you don't count the times I've used my phone) but I mix my card transactions up all the time between cash width drawls, Chip and Pin payments and NFC so I guess the "ask for a pin counter / algo" gets reset when I use a pin in Chip and Pin / ATM.

I believe that after so many NFC payments (without reseting the count) or try and make a purchase over £30 they ask for a pin and my bank will cover any NFC payments on a lost card as long as you make them aware of the loss within a reasonable time period. So personally I'm not too worried about losing my NFC card. They know its not a perfect system (is anything perfect?) so limit their loss by restricting the amounts used on such cards.

EDIT: Esp as a lost card could be used for online transactions as they have the CVV (as they have the card) and losing your card prob means losing your wallet and prob your driving license with your address on it (almost everything a bad actor needs to make an online purchase, just got to hope that Verified by Visa / Mastercard SecureCode kicks in).

<comment><USER31> I actually need the PIN for any payment over €25, which can still be done with NFC. Besides that, I'd say I still need to enter my PIN for small payments roughly once every 2 weeks.

<comment><USER26> I believe the "purchase over £30" in the UK is dependant on the store. Instead of asking I've just use Chip and Pin for such transactions. But yeah never had the "enter your pin" for small NFC payments. Guess the bank thinks I'm a low risk :-p

(Now I've said it I bet the next time I use NFC it will pester me for a pin :-p)

<comment><USER31> In the Netherlands, its something along the lines of "Every x payments, you need a PIN". I'd guess that any payment with PIN resets the counter.

I was discussing with colleagues how smart the interval is. Perhaps the bank is doing some anomaly detection to inform whether a PIN is needed.

</comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER32> I can block the whole magnetic stripe from my smartphone app (Revolut, EU). This whole system (magnetic stripe) is flawed and totally outdated.

<comment><USER33> While you can tell revolut to block transactions that use the magnetic stripe, it doesn't physically disable the stripe, so they can still pull your data from it which maybe enough for them to carry out an attack.

</comment></comment><comment><USER34> ... is there any way to destroy the mag strip a CA ed with a chip?

</comment><comment> adam-a I'm curious how the detector isn't triggered by normal card readers. Surely legitimate untampered readers are reading the magnetic strip too?

<comment><USER20> They mention that if there is a tampered reader, the read is triggered twice.

</comment></comment><comment><USER35> Please someone... Why on earth are there still ATMs with magnetic stripe readers in some countries?

Where I travel I don't run into those anymore. Because if I did it wouldn't work - I've found that with enough magnetic stripe cards in the wallet they effectively de-magnetize each other. I currently have exactly one (very new) VISA debet card with a functioning magnetic stripe, which I use for parking only, as there are still a few very old magnetic stripe machines around. The other cards can't be read. (Someone could put a pinhole camera on the parking lot reader.. doesn't matter, as no pin is entered. Cost is up to ~a dollar or so, so they don't bother with the pin.)</comment>