How to differentiate between Programmer and JVM Exceptions

How to differentiate between Programmer and JVM Exceptions

You cannot do this statically because no such distinction exists.

Any exception defined in the standard Java class libraries may be thrown by application or third-party library code. This includes exceptions (including those that you listed) that are normally thrown by the JVM itself.

  • In some cases, it is a bad (or even terrible) idea to throw a standard exception. For example, it would be a really bad idea for an application to throw something like VerifyError because that has a very specific meaning that an application has no business throwing.

  • In other cases, there are no issues. For example, there is no problem1 with an application throwing NullPointerException explicitly; e.g.

    public void setName(String name) {
        if (name == null) {
            throw new NullPointerException("name must not be null");
        }
        this.name = name;
    }
    

The only possible way to distinguish between an exception that has been thrown by the JVM and by application code is to examine the stack frames from the thrown exception to figure out what class instantiated the exception. (Strictly speaking that doesn't tell you where the exception was thrown ... but it is close enough given that exceptions are nearly always instantiated and thrown in the same statement.)

But even this is not a useful distinction to make. There is no semantically useful difference between an exception thrown by application code, the standard class library or the JVM itself. The source of the exception certainly doesn't say anything about the root cause of the problem; e.g. whether it is due to an application bug, a library bug or something else.

The only useful distinctions are:

  • Error exceptions which you should not attempt to recover from, because they are usually not recoverable.
  • Other unchecked exceptions which may be recoverable, but are typically caused by bugs.
  • Checked exceptions which are often caused by "environmental" problems (such as incorrect file names) that may well need to be reported to the user.

There are a couple of alternative readings of the question:

  • If you wanted to distinguish the exceptions that could be thrown by the JVM from those that can only be thrown by Java code, you could do this by searching the OpenJDK source code for places where exceptions are thrown from native code.

  • If you wanted to distinguish the exceptions that could be thrown by the JVM OR by the standard Java libraries, broaden the search to include Java source code.

However, in both cases the "answer" is not useful (as above), and will depend on the particular Java release you examine.


1 - 1) There are no technical problems with throwing NPE, CCE, AIOOBE and so on. 2) I have never come across a style guide that says you shouldn't do it. 3) I have never seen a coherent explanation of why it should be "frowned on". (If you know of one, please provide a link to it.)


I'm not sure what you mean by JVM exceptions. These are all runtime exceptions that may be thrown by the programmer at any point (exception AssertionError), though it is considered poor style to throw certain exceptions like NullPointerException. The point is, there's no one quality separating the two categories you mention other than their typical usage. All the runtime exceptions extend, either directly or indirectly, RuntimeException.

From the JavaDocs for Throwable:

Only objects that are instances of this class (or one of its subclasses) are thrown by the Java Virtual Machine or can be thrown by the Java throw statement.

Because this same superclass defines all exceptions thrown by either the JVM or a programmer, you can't easily distinguish the two.

Tags:

Java

Exception